Thursday, April 12, 2012

Certain anomalies in binary search runtime

I have a modified version of binary search that takes in an array in sorted order and a value, and returns the smallest possible index of an element that is equal to or larger than the given value (or -1 if the value is larger than the max)



Upon the running the above algorithm, everything works fine and the method works as expected. However, I ran it over different input sizes to measure the runtime.



   for(int i=1;i<=20;i++){  
int size=10*(i*i*i*i);
int[] array=createRandomSortedArray(size);
long startTime=System.nanoTime();
int index=findSmallestIndex(array, needle);
long et=System.nanoTime()-startTime;
System.out.println("To find "+needle+" in "+size+" inputs "+" execution time is "+et+" nanoseconds");
}


And following were the observtions:-



To find 50 in 10 inputs  execution time is 5775 nanoseconds
To find 50 in 160 inputs execution time is 1925 nanoseconds
To find 50 in 810 inputs execution time is 4330 nanoseconds
To find 50 in 2560 inputs execution time is 5293 nanoseconds
To find 50 in 6250 inputs execution time is 3849 nanoseconds
To find 50 in 12960 inputs execution time is 3368 nanoseconds
To find 50 in 24010 inputs execution time is 3849 nanoseconds
To find 50 in 40960 inputs execution time is 11548 nanoseconds
To find 50 in 65610 inputs execution time is 9143 nanoseconds
To find 50 in 100000 inputs execution time is 4812 nanoseconds
To find 50 in 146410 inputs execution time is 4812 nanoseconds
To find 50 in 207360 inputs execution time is 11549 nanoseconds
To find 50 in 285610 inputs execution time is 8661 nanoseconds
To find 50 in 384160 inputs execution time is 8661 nanoseconds
To find 50 in 506250 inputs execution time is 11549 nanoseconds
To find 50 in 655360 inputs execution time is 11067 nanoseconds
To find 50 in 835210 inputs execution time is 11549 nanoseconds
To find 50 in 1049760 inputs execution time is 11549 nanoseconds
To find 50 in 1303210 inputs execution time is 11067 nanoseconds
To find 50 in 1600000 inputs execution time is 12030 nanoseconds


I see that execution time for 10 inputs is significantly higher than its successive 160 input size.
To verify things, I ran the execution for 10 inputs by itself outside the loop and following was the result



To find 50 in 10 inputs  execution time is 962 nanoseconds


Why is that so? Why does this anomaly exist? There are couple of other steps too where run time is slower than its preceding lower input size.





1 comment:

  1. Did you let the VM 'warm up' prior to running your microbenchmark? Try running this code a few thousand times prior to actually recording any results and see if that makes a difference. You can add the following command line argument to see what gets compiled by the JIT:

    -XX:+PrintCompilation

    You can also run your program with

    -Xint

    to turn off all Hotspot optimizations and try to get an apples for apples comparison.

    If this isn't the issue - I suspect there is some constant cost to simply invoking your method. Try increasing the input size linearly and see if you can draw any correlations that way. It's hard to tell when you jump from 10 to 160.

    Lastly, you might want to include a flag that when enabled will log the behaivor (e.g # of comparisons, etc) the code is performing to see if your doing any unnecessary work.

    ReplyDelete