3

我正在使用一个 Java 库:给定一个中缀表达式(1 + 3) + 4,它可以构建一个 AST,如下所示:

                              BinaryIntegerExpression  
                              /          |            \
              IntegerExpression          op         IntegerExpression
                      |                  |                  |
           BinaryIntegerExpression       +           IntegerConstant
           /          |            \                        |
   IntegerExpression  op      IntegerExpression             4
          |           |             |
    IntegerConstant   +       IntegerConstant
          |                         |
          1                         3

基本上,BinaryIntegerExpression 和 IntegerConstant 是 IntegerExpression 的子类。该库有一个抽象类 Visitor,它允许您覆盖 preVisit 和 postVisit 以遍历树。除了那个,我什么都不能碰。

这是我的尝试。我尝试使用简单的递归来生成前缀表达式。它适用于小例子。

public void preVisit(BinaryIntegerExpression expr) {

        if(stop == true)
            return;

        PrefixVisitor left = new PrefixVisitor();
        left.preVisit(expr.getLeft());

        PrefixVisitor right = new PrefixVisitor();
        right.preVisit(expr.getRight());

        str = "( " + expr.getOp().toString() + " " + left.getExpression() + " " + right.getExpression() + " )";
        stop = true;
    }

public void preVisit(IntegerConstant expr) {

        if(stop == true)
            return;

        str = " " + expr.toString() + " ";
    }

但是,我必须处理大小超过 100MB 的表达式,所以内存和性能都有问题。因此,我想使用堆栈优化此过程。任何人都可以给我一个提示吗?谢谢。

========================
编辑:表达式是复杂分析的结果,我只是得到结果来处理它,无法构建从一开始的结果。

4

1 回答 1

4

目前尚不清楚您要做什么,但我会从一开始就将表达式构建到单个 StringBuilder 中。这会快得多,但不会使用更少的内存。一个 100 MB 的文本文件使用 200 MB 来加载,另外 200 MB 作为字符串进行操作,加上你的表达式建议你需要几 GB 的内存。

如果您仍然使用太多内存,我建议将表达式流式传输到文件。处理此问题的通用方法是Appender采用 StringBuilder 和 PrintWriter 的接口。

提示:考虑如何在不创建任何对象的情况下构建文本表达式(至少不直接创建)。如果你这样做,它会快得多。

最简单的解决方案是确保您有足够的堆并使用 CPU 和内存分析器来提高其效率。

于 2013-10-01T13:34:20.180 回答