0
public class Runtime {
    public static void main(String[] args) {
        int[] n = {1,100,1000,10000};

        for (int i=0; i<4; i++) {
            StringRepeater s = new StringRepeater();

            long start = System.nanoTime();
            s.repeatString("hello", n[i]);
            long stop = System.nanoTime();

            long runtime = stop - start;
            System.out.println("T(" + n[i] + ") = " + runtime/1000000000.0 + " seconds");
        }

        for (int i=0; i<4; i++) {
            long start = 0;
            long stop = 0;
            long runtime100 = 0;

            for (int j=0; j<100; j++) {
                StringRepeater s = new StringRepeater();

                start = System.nanoTime();
                s.repeatString("hello", n[i]);
                stop = System.nanoTime();

                runtime100 = runtime100 + (stop - start);
            }

        System.out.println("T(" + n[i] + ") = " + runtime100/100000000000.0 + " seconds");
        }
    }
}

So i've got this code which measures the runtime of repeatString

public class StringRepeater {
    public String repeatString(String s, int n){
        String result = "";
    for(int i=0; i<n; i++) {
        result = result + s;
    }
    return result;
    }
} 

The top part with 1 for loop calculates runtime of 1 run. The bottom part with 2 for loop calculates it based on average of 100. But for some reason the runtime of second part is averagely so much faster especially for lower n. For n=1 its even 100 times faster.

T(1) = 2.3405E-5 seconds
T(100) = 1.47748E-4 seconds
T(1000) = 0.00358515 seconds
T(10000) = 0.173254266 seconds
T(1) = 1.9015E-7 seconds
T(100) = 3.035997E-5 seconds
T(1000) = 0.00168481277 seconds
T(10000) = 0.10354477848 seconds

This is about the typical return. Is my code wrong or is there something else going on. TL:DL why is average runtime so much lower than 1x runtime? You would expect it to be fairly similar right?

5Six
  • 23
  • 3

1 Answers1

0

There are many things that require attention:

  1. It's better to avoid division to monitor execute time because you can have a precision problem. So, a first suggestion: keep speed time in nanoseconds.

  2. The performance difference is probably due to just in time compilation: the first time that compiler executes the code, it takes some time to compile on-the-fly the bytecode. Just to demonstrate this, simply try to invert the loops in your code. I do it for you:

    public class Runtime {
    public static void main(String[] args) {
        int[] n = { 1, 100, 1000, 10000 };
    
        for (int i = 0; i < 4; i++) {
            long start = 0;
            long stop = 0;
            long runtime100 = 0;
    
            for (int j = 0; j < 100; j++) {
                StringRepeater s = new StringRepeater();
    
                start = System.nanoTime();
                s.repeatString("hello", n[i]);
                stop = System.nanoTime();
    
                runtime100 = runtime100 + (stop - start);
            }
    
            System.out.println("T(" + n[i] + ") = " + runtime100 / 100.0 + " seconds");
        }
    
        for (int i = 0; i < 4; i++) {
            StringRepeater s = new StringRepeater();
    
            long start = System.nanoTime();
            s.repeatString("hello", n[i]);
            long stop = System.nanoTime();
    
            long runtime = stop - start;
            //System.out.println("T(" + n[i] + ") = " + runtime / 1000000000.0 + " seconds");
            System.out.println("T(" + n[i] + ") = " + runtime  + " seconds");
        }
    
    
    }
    
    public static class StringRepeater {
        public String repeatString(String s, int n) {
            String result = "";
            for (int i = 0; i < n; i++) {
                result = result + s;
            }
            return result;
        }
    }
    }
    

When I run this code on my machine I obtain the following results:

T(1) = 985.31 seconds
T(100) = 109439.19 seconds
T(1000) = 2604811.29 seconds
T(10000) = 1.1787790449E8 seconds
T(1) = 821 seconds
T(100) = 18886 seconds
T(1000) = 1099442 seconds
T(10000) = 121750683 seconds

You can see that now the 100's loop now is slower than single round execution. This is because it is executed before now.

3 - If you observe the above result you probably notice that now the situation is simply the opposite respect the initial situation. Why? In my opinion, this is due to the garbage collector work. In the bigger cycle, garbage collection has more work to do, just because there are many temporary variables to garbage.

I hope it helps you.

xcesco
  • 4,690
  • 4
  • 34
  • 65
  • Thanks, i also came to the same conclusion shortly after i posted this. I just simply put an extra 100 times in front of my 1 time. But thanks for the confirmation. – 5Six Oct 16 '18 at 22:31