0

I'm currently working on a schoolproject that will parse text files that contains different instruction of how to move. These instructions are then placed out in a tree structure that always bransch to the right with an new instruction and to the left with how much each instruction can go.

It will looks something like this:

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

Anyways without going into to much more details on the specifics of my program my question to you is how I can improve this part of the program to make it become faster?

As you can see I have tried using the stringbuilder to speed up the process but it didn't do much different and at this point I'm kind of out of ideas so any help would be greatly appreciated.

This program is tested with alot of test cases and if any of them takes longer than 7 seconds it fails and that is now the case.

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;
            }   
}
Dreamus
  • 45
  • 1
  • 9
  • 1
    I don't think a tree is the right structure for this.. – MightyPork Jan 04 '15 at 19:58
  • It's a part of the assignment so I don't have so much choice in the matter. – Dreamus Jan 04 '15 at 20:00
  • Probably this is better fit for http://codereview.stackexchange.com – Gábor Bakos Jan 04 '15 at 20:04
  • 1
    I would not be to worried about how long a program takes to run for a school project the idea is to get the concept of the assignment, in this case I am guessing a tree. worry about runtime after class to improve the program. – David Coler Jan 04 '15 at 20:04
  • Well this program is tested by a system that checks that the runtime isn't to long and if it's over 7 seconds for any of the different tests that are performed you don't pass the assigment and therefore I need to improve the programs runtime. – Dreamus Jan 04 '15 at 20:09
  • You could replace your switch statement for a polymorphic mapping system. That way you can access which operation should be done in constant time. I also suggest retitling the question to something like "what's causing my program to process things longer than it should", explaining your limitation of 7 seconds. – Vince Jan 04 '15 at 20:24
  • If you want to improve the performance, I suggest you use a CPU profiler to see where it is spending the most time. – Peter Lawrey Jan 04 '15 at 20:52
  • BTW Building a complex StringBuilder is bound to be expensive, however you could have something even more expensive and a profiler is the best way to find this. – Peter Lawrey Jan 04 '15 at 20:53
  • @PeterLawrey especially since new `StringBuilder`s get created with every call of `treeSearch`. – Tedil Jan 04 '15 at 21:24

1 Answers1

0

After some thinking and as Tedil and OeterLawrey pointed out the problem was that I had done a big misstake by making a new StringBuilder for each call of treeSearch and therefore my program was really slow. Instead of returning each Stringbuilder I made a variable str instead and just returned it with a new method to the main program and by doing that I resolved the problem.

Thanks for the help guys!

Dreamus
  • 45
  • 1
  • 9
  • That's great, but it was gotten by guessing. If you tried [*this*](http://stackoverflow.com/a/317160/23771) it would show you exactly what the problem is, without any guessing. – Mike Dunlavey Jan 05 '15 at 15:14