Wednesday, April 16, 2008

System.arraycopy vs. Iterative loops for copying arrays



Well, I must say I am totally bewildered. Reading into “Java 2: The Complete Reference” by Herbert Schildt, I stumbled upon a method called “arraycopy()”, defined by the class System. This method is supposed to copy one array into another. This what the book says about the method:

The arraycopy( ) method can be used to copy quickly an array of any type from one place to another. This is much faster than the equivalent loop written out longhand in Java....


A quick search in the web about the method conformed this, a website recommending the use of arraycopy() over iterative method says:

….Besides accomplishing the same result with less code, this approach has the added advantage of being faster, since arraycopy is implemented as a native method, and will generally execute faster than equivalent code written in Java. This advantage can be particularly significant with large arrays or where many arrays are being copied.


So, I decided to try out how much quicker is System.arraycopy over iterative loops. So, I wrote a java code to test it out:


public class TimeCompare {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int a[] = new int[1000000];
int b[] = new int[1000000];
int c[] = new int[1000000];
long start, end;

for(int i = 0; i < 1000000; i++){
a[i] = i;
c[i] = i;
b[i] = i+1;

}


start = System.currentTimeMillis();
for(int i = 0; i < a.length; i++){
a[i] = b[i];
}
end = System.currentTimeMillis();

System.out.println("Time taken to copy in milliseconds: " +
(end - start));

start = System.currentTimeMillis();
System.arraycopy(b, 0, c, 0, c.length);
end = System.currentTimeMillis();

System.out.println("Time taken to copy in milliseconds: " +
(end - start));

}

}


The logic is to get the start time, end time of the iterative way of copying and thereby calculate the total time it takes to complete the operation. Similarly, I also find the time taken by System.arraycopy and print it out both (iterative method followed by System.arraycopy). I am at loss to explain what I saw when I ran the program.

During my first execution, I got an output along the expected lines (iterative method takes more time to run):



Just out of curiosity, I ran the program using command prompt to see if it takes lesser time than using the IDE. This is what I got!



Iterative way, takes far less time than arraycopy!

Bewildered, I ran it two more times. Thankfully, the arraycopy method faired better, though the iterative method clocked different times – that is expected considering the load of the CPU during the execution.




But then, I returned to Netbeans IDE and ran the program again. This is what I got!




Both have taken almost the same time (I say almost in spite of both being 0, because the difference might have been subtle to be displayed in scale of milliseconds).

I ran it again. System.arraycopy() takes more time than iterative method!




So why is there so much discrepancy each time I run the program? How faster is System.arraycopy() , than the iterative method? If you know the answer please do write it down as a comment.

5 comments:

Thierry BODHUIN said...

The mistake is about how do a performance test. First you need to do a warm performance test (the compilation thread may interfere here):
Do the performance evaluation after enough time.
May be create 2 method that execute the two test.
Call them enough (in order to have been compiled surely by the hotspot compiler) before the performance evaluation.
, and also try to increase the time spent in the instruction by incrementing the array size or cycle number in order to reduce the effect of other thread execution (like Garbage Collection Thread, ... that interfere with your result).

Thierry Bodhuin

Ramesh Subramanian said...

Thierry Bodhuin,

Thanks for your suggestion. I must say that your suggestion did help. I tried creating a class that defines the methods for iteration & arraycopy, & called them in the main method. Now the program, runs as expected. 4 out of 5 times that I ran the program, arraycopy seems to do a far better job than the iteration method. May be still increasing the size of the array, will make it 5 out of 5!

Thanks,
Ramesh Subramanian

Sarav said...

Buddy....seems u r doing a good job. Keep it up!

Olli Nevalainen said...

See http://forums.sun.com/thread.jspa?messageID=3978729#3980048 for an explanation for this.

nick said...

Well dude, with a test like this, the numbers are just noise. Perhaps you didn't realise that the system timer only has a resolution of about 10ms, so your time values are just too small to be meaningful or accurate. Scaling this up by 1000 gives the following results:
which are more or less consistent, and System.arraycopy is always faster.
Time taken to copy in milliseconds: 3070
Time taken to copy in milliseconds: 2363