是什么导致我的程序处理的时间超过应有的时间?

时间:2015-01-04 19:56:57

标签: java performance

我目前正在开发一个学校项目,该项目将解析包含不同移动指令的文本文件。然后将这些指令放在一个树结构中,该树结构总是用新指令向右括起来,在左边用每条指令可以走多少。

它看起来像这样:

           FORW
          /    \
         2      LEFT
               /    \
              90    Rep
                   /   \
                FORW    FORW
               /       /    
              4       2

无论如何,如果没有详细了解我的程序细节,我的问题就是如何改进程序的这一部分以使其变得更快?

正如你所看到的,我已经尝试过使用stringbuilder来加速这个过程,但它并没有太大的不同,在这一点上我有点想法,所以任何帮助都会非常感激。

这个程序经过了很多测试用例的测试,如果它们中的任何一个需要超过7秒,它就会失败,现在就是这种情况。

import java.util.ArrayList;


// Ett syntaxträd

public class CreateLines{

    private boolean penDown;                                // 1 om pennan är nere 0 om inte.
    private double x1, x2, y1, y2;                      // x,y-koordinat
    private int degrees;                                // vinkel v
    private String color;                               // nuvarande färg
    private double piDegrees;
    private double decimals;
    private ArrayList<String> result;                   


    public CreateLines() {
        penDown = false;
        x1 = 0;
        x2 = 0;
        y1 = 0;
        y2 = 0;
        degrees = 0;
        color = "#0000FF";
        // For optimization.
        decimals = 100000;

    }

    public StringBuilder treeSearch (Operation tree) {
                // Some variables we use down here:
                double x1 = this.x1;
                double y1 = this.y1;
                double x2;
                double y2;
                int numberNode;

                StringBuilder str = new StringBuilder();

                switch (tree.operation) {
                    case FORW: 
                        piDegrees = Math.PI*degrees/180;
                        numberNode = tree.evaluate();
                        x2 = x1 + (numberNode * Math.cos(piDegrees));
                        y2 = y1 + (numberNode * Math.sin(piDegrees));
                        x2 = (double)Math.rint(x2 * decimals) / decimals;
                        y2 = (double)Math.rint(y2 * decimals) / decimals;
                        this.x1 = x2;
                        this.x2 = x2;
                        this.y1 = y2;
                        this.y2 = y2;

                        // If penDown then we print otherwise not.
                        if (penDown){
                            str.append(color + " " + x1 + " " + y1 + " " + x2 + " " + y2 + "\n");
                            if(tree.right == null){
                                return str;
                            }
                            return str.append(treeSearch((Operation) tree.right));
                        }
                        else{
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }
                    case BACK:
                        piDegrees = Math.PI*degrees/180;
                        numberNode = tree.evaluate();
                        x2 = x1 - (numberNode * Math.cos(piDegrees));
                        y2 = y1 - (numberNode * Math.sin(piDegrees));
                        x2 = (double)Math.rint(x2 * decimals) / decimals;
                        y2 = (double)Math.rint(y2 * decimals) / decimals;
                        this.x1 = x2;
                        this.x2 = x2;
                        this.y1 = y2;
                        this.y2 = y2;

                        // If penDown then we print otherwise not.
                        if (penDown){
                            str.append(color + " " + x1 + " " + y1 + " " + x2 + " " + y2 + "\n");
                            if(tree.right == null){
                                return str;
                            }
                            return str.append(treeSearch((Operation) tree.right));
                        }
                        else{
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }       

                    case LEFT: 
                        numberNode = tree.evaluate();
                        this.degrees = degrees+numberNode;
                        if (penDown){
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }
                        else{
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }   

                    case RIGHT: 
                        numberNode = tree.evaluate();
                        this.degrees = degrees-numberNode;
                        if (penDown){
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }
                        else{
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }

                    case DOWN: 
                        this.penDown = true;
                        if(tree.right == null){
                            return str;
                        }
                        return treeSearch((Operation) tree.right);

                    case UP: 
                        this.penDown = false;
                        if(tree.right == null){
                            return str;
                        }
                        return treeSearch((Operation) tree.right);

                    case COLOR: 
                        this.color = tree.color.toUpperCase();
                        if (penDown){   
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }
                        else{
                            if(tree.right == null){
                                return str;
                            }
                            return treeSearch((Operation) tree.right);
                        }   
                    case REP:
                        // if we got a rep instruction to the left we 
                        if(tree.right == null){
                            for(int i = 0; i < tree.rep; i++){
                                str.append(treeSearch((Operation) tree.left));
                            }
                            return str;
                        }   

                        else {
                            for(int i = 0; i < tree.rep; i++){
                                str.append(treeSearch((Operation) tree.left));
                            }
                            return str.append(treeSearch((Operation)tree.right));
                        }

                }
                assert false; // borde aldrig kunna hända
                return null;
            }   
}

1 个答案:

答案 0 :(得分:0)

经过一番思考后,Tedil和OeterLawrey指出问题是我通过为每次调用treeSearch创建一个新的StringBuilder而做了一个很大的错误,因此我的程序非常慢。而不是返回每个Stringbuilder我改为创建一个变量str,然后用一个新方法将它返回给主程序,通过这样做我解决了问题。

感谢帮帮!