Tip : Don’t use shorts for loop indexes !

After a post I read on a french forum, i asked myself of the performances using shorts as loop indexes for loop with few iterations (less than 32768).

At first view, it can be tempting because we save 2 octets, so why use an int instead a short ?

But, when we think of that, we see that the int is more adapted. Indeed, it's more performant.

Why ?

In Java language, all the operations on integers are made in int. Thus, if we use a short as loop index, at each iterations, a typecasting will be made, that's really heavier than a simple affectation to int.

Here were my first results :

Time for int : 1441 ms
Time for short : 3015 ms

The short version is two times slower !

But like Jean have said, my first test was not correct at all because it doesn't consider some issues that could occurs with micro-benchmarks.

So I write a new test using a Java Benchmarking framework from Brent Boyer. Here is a little test with that framework :

package com.wicht;

import bb.util.Benchmark;
import java.util.concurrent.Callable;

public class ShortIndexesLoop {
    public static void main(String[] args) {
        Callable callableInt = new Callable(){
            public Long call() throws Exception {
                long result = 0;

                for (int f = 0; f < 32760; f++){
                      result += f;
                  }

                return result;
            }
        };

        Callable callableShort = new Callable(){
            public Long call() throws Exception {
                long result = 0;

                for (short f = 0; f < 32760; f++){
                      result += f;
                  }

                return result;
            }
        };

        try {
            System.out.println("Result with int " + new Benchmark(callableInt));
            System.out.println("Result with short " + new Benchmark(callableShort));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

And here are the results :

Result with int first = 695.181 us, mean = 43.233 us (CI deltas: -49.358 ns, +74.073 ns), sd = 42.938 us (CI deltas: -11.634 us, +16.426 us)
Result with short first = 733.224 us, mean = 45.679 us (CI deltas: -62.975 ns, +63.932 ns), sd = 45.567 us (CI deltas: -5.877 us, +8.020 us)

So the results are lower. This time, the short version is 5.657% slower than the int version. Note that this can vary a lot depending on your configuration.

I talk here of for loops, but the case is the same when you use while loops with indexes.

Here are also the results with long, double and float versions :

Result with long first = 816.555 us, mean = 104.771 us (CI deltas: -236.563 ns, +344.219 ns), sd = 143.295 us (CI deltas: -39.149 us, +63.700 us)
Result with float first = 1.018 ms, mean = 58.055 us (CI deltas: -87.036 ns, +113.537 ns), sd = 70.757 us (CI deltas: -14.269 us, +19.962 us)
Result with double first = 912.115 us, mean = 57.918 us (CI deltas: -66.644 ns, +91.312 ns), sd = 55.185 us (CI deltas: -12.617 us, +25.160 us)

We can see that the long version is the slowest one and that float and double are equivalent but slower than int and short.

To conclude, always use int as loop indexes add a very little improvements of performances, but not a great thing and do not use long for loops indexes.

Related articles

  • How to write correct benchmarks
  • My Java Benchmarks on GitHub
  • EDDI 0.4.1 : Loops and better assembly generation
  • EDDIC 0.8.1 : do while loop and better optimization
  • The reserved keywords of the Java Language
  • eddic 1.2.2 - Performances, improved optimizations and additions to standard library
  • Comments

    Comments powered by Disqus