Saturday 20 May 2017

Benchmark your code

Objective: Let us discuss a few common techiques of benchmarking your code/service and similar concepts. These concepts are a general understanding which I have developed from time to time and would only go into the very simple and basic benchmarking techniques.


Q1: There are many profilers for profiling a JVM code. But is there a reliable way to quickly get the cpu time of my code ?


A: Yes there is a quick way. And "java.lang.management.ManagementFactory" provides the solution. ThreadMXBean's getCurrentThreadCpuTime will give you a much accurate cpu time. Do refer to the below test code which demonstrates that the sleep and wait of several milli seconds is correctly discarded from the total cpu time by getCurrentThreadCpuTimecodeLink::MeasureCpuTime. This is a nice example profiling a sum method to output the sum of all elements in a list.
I will be a very good practice to perform such instrumentation for all important code blocks in unit testing itself. A simple profile function as mentioned in the above code will do the same.

Q2: Hey! In the above profiling, I found that the first run is always taking way more than the the subsequent runs. Why is it so ?

A: Yes. It is because in the first run the method ("sum") is invoked for the first time. There is an extra CPU cost associated with loading that particular method in code cache of heap. This extra cost is only for the first invocation. Also, for subsequent runs the JVM hotspot would have further optimised the byte code especially by removing the redundant operations corresponding to your method.

Q3: Is there any simple way to benchmark the heap foot print of my code ?

A: Yes there is a way. But, actual CPU time profiling is much easier in theory. Again ManagementFactory provides you a function (getGarbageCollectorMXBeans) to get all garbage collection information. The code link link::MeasureHeapHotspot shows the heap usage pattern for fold list to string operation. Notice how the heap usage is always high in the unoptimised approach. And the optimised approach is not only readable but also has no heap footprint in the subsequent runs.
                Despite of this explanation, there are many easily available instrumentation and profiling libraries. It is better to use these libraries or build something on these lines in the long run. Also, ideally those instrumentation metrics should be pushed via mbeans and not by print statements :)


more to follow ....

No comments:

Post a Comment