Performance Analysis

The process of optimizing the performance of a system, often with the help of a profiler tool, and often at the cost of complexity and developer sanity.

A quick introduction to some of the terms:

Things to keep in mind

  • There is an art to all of this, so merely gaining the possession of a fancy profiler tool doesn’t mean you are almost done.
  • Performance costs, so Customers should make the choice around acceptable performance. Is a 50% reduction in an operation’s time move valuable than a new feature?
  • Code optimization often increase the complexity of the code and has a reasonable chance of introducing bugs. Be careful.
  • Know when to stop. Set a target duration for a scenario.
  • Profiler tools will effect the execution of your application, so don’t blindly accept everything it tells you as the truth.
  • Budget your efforts by the amount of improvement it will give you. Speeding up a part of the system that only consumes 1% of the execution time is probably a waste of effort.
  • If human perception is the arbitrator of good enough performance, then you might have a lot of cheaper tricks at hand. Say a progress bar.


  • Try to code up a scenario as a test case for easier and more stable execution.
  • Throw away code changes that don’t show sufficient performance improvements.
  • Feel free to use; System.out.println(“** “+System.currentTimeMillis());
  • Average out your results
  • Watch out for the first run of a scenario, class loading, JIT compilication, data caching can radically change it from subsequent runs

Locating Hotspots

Locating code to optimize based on hunches will lead to a lot of wasted effort on larger projects.

  • Large amounts of time spent within a method.
  • Methods called many times that produce the same result each time – Cache the result.
  • Large number of objects allocated of a specific type

Code Optimizations

Once you have found a potential section of the system to optimize, which code transformations would be relevant?

Do Less. Work Concurrently. Move Calculations. Cheat.

  • Caching the result of a calculation can save a lot of time. If the total result is too difficult, sometimes you can cache results for parts of the calculation, only needing the subset of the full calculation on demand.
    • Downsides: It can also significantly complicate the code if the calculation could produce different results over time. Watch out for mutable state.
  • Fast path code. If a certain case occurs lots of the time investigate if it can be handled by some special case code in a faster way.
    • Downsides: More code, and branches complicate reading of the code later
  • Concurrent execution. Machines now tend to have many cores and so support concurrent execution of code. In Java this probably means threads.
    • Downsides: Where to begin? Deadlocks, object aliasing, complexity, and so on.
  • Asynchronous Execution. If you don’t need the result of a calculation immediately, let in run in the background and come back later. This can often be used at the UI level. In java see FutureTask class for one approach.
    • Downsides: This is constrained version of concurrent execution.
  • Reduce IO. CPU’s are insanely fast, but disks and network aren’t. Hold back on flushes of OutputStreams. Order accesses of storage to minimize seek times.
    • Downsides: Probably more code, holding onto data longer could increase memory demands.
  • Reduce Correctness. How precise does a result need to be? Often heuristics will generate an approximate result significantly cheaper than a fully correct result. Perhaps an approximate answer now is good enough until the complete answer is available, as an example interlacedrendering of PNG images.
    • Downsides: Complexity, changing result could confuse clients of the calculation.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply