9 tips to Increase your Java performance - 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"));
Let us verify this using JMH benchmarks.
The results unit is
operations/second
(op/s
). More the number higher the performance is.
// Faster π > ~18000 op/s
@Benchmark
public HashSet usingConstructor() {
var arr = new int[100000];
for (var i = 0; i < 100000; i++) {
arr[i] = i;
}
List list = Arrays.asList(arr);
var set = new HashSet<>(list);
return set;
}
// Slower πΆββοΈ > ~17100 op/s
@Benchmark
public HashSet usingAddAll() {
var arr = new int[100000];
for (var i = 0; i < 100000; i++) {
arr[i] = i;
}
List list = Arrays.asList(arr);
var set = new HashSet<>();
set.addAll(list);
return set;
}
The
construtor
version provides ~1000 op/s more than theaddAll
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;
}
The addAll
is almost twice as fast as the add
version.
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;
}
entrySet
can run 9000
operations more than its keySet
variant in a second.SingletonList
instead of an array
with single element.// Faster π
var list = Collections.singletonList("S");
// Slower πΆββοΈ
var list = new ArrayList(Arrays.asList("S"));
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()));
More about EnumSet here.
// 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;
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;
}
Character
// Faster π
var r = 'R' ;
var g = 'G' ;
var b = 'B' ;
// Slower πΆββοΈ
var r = "R" ;
var g = "G" ;
var b = "B" ;
// 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";
....
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.
#java #web-development