I am testing performance on integer addition in Java. The way I did that is by summing up billions of integers. The sample file I use for testing is a 1G binary file. My program is as simple as shown in the snippet below.
int result = 0;
FileChannel fileChannel = new FileInputStream(filename).getChannel();
long fileSize = fileChannel.size();
intBuffer = fileChannel.map(MapMode.READ_ONLY, startPosition, fileSize).asIntBuffer();
try {
while (true) {
result += intBuffer.get();
}
} catch (BufferUnderflowException e) {
System.out.println("Complete reading");
}
As you can see from above, it simply executes two operations in each loop
- read integer from file
- integer addition
This program ran about 2 minutes on my machine. I also did another test run without addition, by changing result += intBuffer.get() to result = intBuffer.get() (shown as in following snippet).
int result = 0;
FileChannel fileChannel = new FileInputStream(filename).getChannel();
long fileSize = fileChannel.size();
intBuffer = fileChannel.map(MapMode.READ_ONLY, startPosition, fileSize).asIntBuffer();
try {
while (true) {
result = intBuffer.get();
}
} catch (BufferUnderflowException e) {
System.out.println("Complete reading");
}
The entire program in this case turned out to complete within 1 second. Compared to its sibling variant above, it seems integer addition dominate the CPU time compared to IO read.
I wrote another benchmark program just for justify my guess, it does the same number of additions as the above example.
int result = random.nextInt();
int other = random.nextInt();
int num = 1073741824 / 4;
while(num-- > 0) {
result += other;
}
With the same amount of integer additions plus the integer incremental operations, this program finishes less than 1 second.
My question is
- What caused the the major timing difference between these runs? Does Java compiler does something to optimize the last one?
Any thoughts are appreciated.
That’s because disk I/O is very slow compared the CPU.
In the first case, you’re reading from a file. So you’re bound by disk-access.
In the second case, it’s all in the CPU.
So this has nothing to do with the speed of addition.
As for why
result = intBuffer.get()seems to be very fast: (pulled from comments)Two possible reasons I can think of:
*So subsequent passes will be very fast. It’s easy to test for this case by re-ordering the tests or clearing the I/O cache each time