garlicbulb
garlicbulb

Reputation: 306

Integer addition performance in Java

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

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

Any thoughts are appreciated.

Upvotes: 3

Views: 1328

Answers (3)

Mysticial
Mysticial

Reputation: 471229

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.

  • The first case is limited by the speed of your disk.
  • The second case is (probably) limited by the speed of the random number generator.

As for why result = intBuffer.get() seems to be very fast: (pulled from comments)

Two possible reasons I can think of:

  • Dead Code Elimination by the JIT is optimizing out all but the last iteration.
  • I/O buffering: The OS is buffering the entire file into memory after the first read.*

*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

Upvotes: 4

msi
msi

Reputation: 2639

This is because I/O access is your bottle neck. Count time only on addition phase. You can always load all data to RAM (an int array for example) and start counting time from this point.

Whatever benchmark you do, keep in mind that data preparation phase shouldn't be counted to algorithm's execution time.

Upvotes: 0

Martijn Courteaux
Martijn Courteaux

Reputation: 68847

The big difference is that you are doing file IO. Summing the integers isn't the problem. But it's reading them. I'm not very sure, but I think that reading one GB of data in two minutes is acceptable.

Upvotes: 1

Related Questions