How to reduce GC and increase performance in JAVA

Every day we write a piece of code that includes a loop. Some loop we do for a few lists of objects where some loop is for the huge group of objects. Sometimes we need to optimize our block of code in order to improve the performance of the functionality and sometimes to reduce garbage collection which is a major factor when writing code in JAVA language.

Working with collection

Sometimes we need to traverse through thousands of items where the performance is never really a concern when we use JAVA collection such as ArrayList and HashSet. But when we traverse through a million items, the performance becomes a headache.

For such situation, we really need to think about the loop. Let us see in the below section with an example, how we can really increase the performance of our code in a simple way.

Working with loop

Most of the programming language has a simple syntax which allows programmers to loop the collections. Here is the simple forEach loop which is really easy to write.

public List<Integer> streamSingleThread(BenchMarkState state){
  List<Integer> result = new ArrayList<>(state.testData.size());
  state.testData.stream().forEach(item -> {
    result.add(item);
  });
  return result;
}
public List<Integer> streamMultiThread(BenchMarkState state){
  List<Integer> result = new ArrayList<>(state.testData.size());
  state.testData.stream().parallel().forEach(item -> {
    result.add(item);
  });
  return result;
}

Traditional for loop is very compact and more verbose.

public List<Integer> forCStyle(BenchMarkState state){
  int size = state.testData.size();
  List<Integer> result = new ArrayList<>(size);
  for(int j = 0; j < size; j ++){
    result.add(state.testData.get(j));
  }
  return result;
}

Lets see the performance of both the loop

Benchmark                               Mode  Cnt   Score   Error  Units
TestLoopPerformance.forCStyle           avgt  200  18.068 ± 0.074  ms/op
TestLoopPerformance.forEach             avgt  200  30.566 ± 0.165  ms/op

When we use traditional C style for loop JVM simply increases an integer, then reads the value directly from the memory which makes this very fast. But JVM converts forEach to an iterator and call hasNext() method with every object which makes forEach slower than the traditional for loop.

Leave a Reply

Your email address will not be published. Required fields are marked *