9 tips to Increase your Java performance ☕️ 🚀 🚶‍♂️

Sendil Kumar - Jul 20 '19 - - Dev Community

Any fool can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler

But the itch to write a high performance code is always there for any developer. Let us see how to make Java code to run even faster.

Note: The JVM optimizes the code efficiently. So you do not need to optimize it for a general use cases. But if you want to drain the maximum performance out of JVM. Here we go.

All the tests are taken in OpenJDK 12.0.1 in a Macbook Pro 2017 laptop.

1. Instantiate in constructor

If your collections are initialized only once, it is better to initialize the values in the collection constructor itself rather than instantiating the collections and setting the values using addAll.

// Slower 🚶‍♂️
Set<String> set = new HashSet<>();
set.addAll(Arrays.asList("one", "two", "three"));

// Faster 🚀
Set<String> set = new HashSet<>(Arrays.asList("one", "two", "three"));
Enter fullscreen mode Exit fullscreen mode

Let us verify this using JMH benchmarks.

The results unit isoperations/second (op/s). More the number higher the performance is.

@State(Scope.Thread)
public static class MyState {

    @Setup(Level.Trial)
    public void doSetup() {
        var arr = new Integer[100000];
        for (var i = 0; i < 100000; i++) {
            arr[i] = i;
        }
        list = Arrays.asList(arr);
    }

    public List list;
}

// Faster 🚀 > ~148,344 op/s
@Benchmark
public HashSet usingConstructor() {
    var set = new HashSet<>(list);
    return set;
}

// Slower 🚶‍♂️ > ~112,061 op/s
@Benchmark
public HashSet usingAddAll() {
    var set = new HashSet<>();
    set.addAll(list);
    return set;
}
Enter fullscreen mode Exit fullscreen mode

The construtor version provides ~36000 op/s more than the addAll version.


2. AddAll is faster than Add

Similarly, addAll provides higher operations per second when compared with add. So next time when you are adding something to an array make sure that you pile them and add it using addAll.

// Slower 🚶‍♂️ ~116116op/s
@Benchmark
public ArrayList<Integer> usingAdd() {
    var a = new int[1000];
    for (var i = 0; i < 1000; i++) {
        a[i] = i;
    }


    var arr = new ArrayList<Integer>();
    for (var i = 0; i < 1000; i++) {
        arr.add(a[i]);
    }

    return arr;
}

// Faster 🚀 ~299130 op/s
@Benchmark
public ArrayList<Integer> usingAddAll() {
    var a = new Integer[1000];
    for (var i = 0; i < 1000; i++) {
        a[i] = i;
    }

    var arr = new ArrayList<Integer>();
    arr.addAll(Arrays.asList(a));
    return arr;
}
Enter fullscreen mode Exit fullscreen mode

The addAll is almost twice as fast as the add version.


3. Use EntrySet for Map over KeySet

Do you iterate a lot over the map? Then use entrySet over the keySet.


// Slower 🚶‍♂️ ~37000 op/s
@Benchmark
public HashMap<Integer, Integer> keySetIteration(Blackhole blackhole) {
    var someMap = new HashMap<Integer, Integer>();

    for (var i = 0; i < 1000; i++) {
        someMap.put(i, i);
    }

    var sum = 0;
    for(Integer i: someMap.keySet()) {
        sum += i;
        sum += someMap.get(i);
    }
    blackhole.consume(sum);
    return someMap;
}

// Faster 🚀 ~45000 op/s
@Benchmark
public HashMap<Integer, Integer> entrySetIteration(Blackhole blackhole) {
    var someMap = new HashMap<Integer, Integer>();

    for (var i = 0; i < 1000; i++) {
        someMap.put(i, i);
    }

    var sum = 0;
    for(Map.Entry<Integer, Integer> e: someMap.entrySet()) {
        sum += e.getKey();
        sum += e.getValue();
    }

    blackhole.consume(sum);

    return someMap;
}
Enter fullscreen mode Exit fullscreen mode

The entrySet can run 9000 operations more than its keySet variant in a second.

4. Use SingletonList instead of an array with single element.

// Faster 🚀
var list = Collections.singletonList("S"); 

// Slower 🚶‍♂️
var list = new ArrayList(Arrays.asList("S"));
Enter fullscreen mode Exit fullscreen mode

5. Use EnumSet instead of HashSet. EnumSet is much faster.

// Faster 🚀
public enum Color {
    RED, YELLOW, GREEN
}

var colors = EnumSet.allOf(Color.class);

// Slower 🚶‍♂️
var colors = new HashSet<>(Arrays.asList(Color.values()));
Enter fullscreen mode Exit fullscreen mode

More about EnumSet here.


6. Do not initialize objects at will. Try to reuse at the maximum.

 // Faster 🚀
 var i = 0 ;
 i += addSomeNumber();
 i -= minusSomeNumber();
 return i;


 // Slower 🚶‍♂️
 var i = 0 ;
 var j = addSomeNumber();
 var k = minusSomeNumber();
 var l = i + j - k;
 return l;
Enter fullscreen mode Exit fullscreen mode

7. Use String.isEmpty() method to check whether the String is empty.

String is a byte[] and isEmpty just checks the length of an Array. So it is much faster.

public boolean isEmpty() {
        return value.length == 0;
    }
Enter fullscreen mode Exit fullscreen mode

8. If you are using String with a single character replace them with a Character

 // Faster 🚀
 var r = 'R' ;
 var g = 'G' ;
 var b = 'B' ;


 // Slower 🚶‍♂️
 var r = "R" ;
 var g = "G" ;
 var b = "B" ;
Enter fullscreen mode Exit fullscreen mode

9. Use StringBuilder wherever you can.


// Faster 🚀
StringBuilder str = new StringBuilder(); 
str.append("A"); 
str.append("B"); 
str.append("C"); 
str.append("D"); 
str.append("E"); 
....

// Slower 🚶‍♂️
var str = "";
str += "A";
str += "B";
str += "C";
str += "D";
str += "E";
....
Enter fullscreen mode Exit fullscreen mode

But when you have to do a single concatenation. instead of using a StringBuilder it is faster to use +.


If you have an interesting performance tip / something is wrong, please leave that in the comment.

You can follow me on Twitter.

If you like this article, please leave a like or a comment. ❤️

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player