How to identify critical code path
If multiple threads execute the same code execution path, that code path becomes your critical path. In this article, Ram Lakshmanan explains why it’s important to identify critical code path, how to do it and offers a few best practices.
Before answering the question ‘How to identify critical code path?’ let me answer another relevant question: ‘Why should you identify critical code path?’
Why identify critical code path?
There are a couple of answers to it:
- Performance Optimization
- Accurate Smoke Test
In most applications, we have observed that less than 5% of application code accounts for more than 90% of code execution. Thus, if you can optimize this 5% of code, you can improve your entire application’s performance significantly. It’s the best ROI. You can save a significant amount of time in not analyzing the remaining 95% of code.
Accurate test suite
You can write highly targeted unit tests to exercise the critical code path and make your application bullet-proof. In fact, these tests can act as your application’s smoke test. It can be integrated into your CI/CD pipeline. This sort of accurate test suite reduces over-all test execution time. It can also reduce the test data setup time in the backend systems.
Now let’s get back to our original question: How to identify critical code path? This is where thread dumps come in handy.
Thread dumps are the snapshot of all threads running in the application at given moment. It contains detailed information about each thread including its stack trace. Below is the information provided for the “InvoiceGeneratedQC-A99-6” thread in the thread dump.
The above-mentioned stack trace tells you the code execution path of the “InvoiceGeneratedQC-A99-6” thread. This thread has executed 9 methods in the order (1 – 9), as shown in Fig 1.
Thread executed the java.lang.Thread.run() method first, then it went on to execute java.util.concurrent.ThreadPoolExecutor$Worker.run() method from there it went on to execute other methods until com.buggycompany.rt.util.ItinerarySegmentProcessor.setConnectingFlight().
If multiple threads execute the same code execution path, that code path becomes your critical path. You can group stack trace of all the threads, combine them together to form one single call stack tree & from there you can identify the critical code execution path.
Call Stack Tree
Tools like fastthread.io can group stack trace of all the threads and generate one single call stack tree. You can drill down & up on this tree to see the critical code path. Below is the sample call stack tree generated by ‘fastThread.io’. You are welcome to go here to see the call stack tree from a live report.
You can keep drilling down to see the code execution path. Fig 3 shows the drilled down version of a particular branch in the Call Stack Tree diagram.
Call Stack Tree shows you the class name, method name and line of the code that has been executed and a number of threads that have executed the line of code.
From the above element in the Call Stack Tree, you can identify that call() method in buggyCompanyCallable.java is executed by 9 threads. Since 9 threads are executing this method, it’s a good candidate to be categorized as critical code path.
Note that Call Stack Tree will contain code from Java, external frameworks, and libraries because your application executes those codes as well. When writing focused tests or optimizing the performance of the critical code path, you can ignore or give low priority to that external code, as you have very little control over them.
Capture thread dumps from production
It’s extremely hard (if not impossible) to mirror production traffic in a test environment. As you need to identify the critical code execution path in production, it’s ideal to capture thread dumps from production environment instead of test or other lower environments.
Capture thread dumps during peak volume time
It’s ideal to capture thread dumps during peak volume time period. It’s where you can observe maximum possibilities of application code exercise.
Capture 3 – 5 thread dumps
As thread dump is a snapshot of a particular point in time, it’s ideal to capture at least 3 – 5 thread dumps to see a few possibilities of code execution path. There are multiple options to capture thread dumps.
Use your favorite option to capture the thread dump.