Java Performance: The Definitive Guide, Chapter 1 and 2

Death by 1,000 cuts, “Thrashing”, Occam’s Razor, mesobenchmarks, warm-up period, and think time.

Chapter 1

  • Specify the platform you are optimizing for; e.g., Java 7 update 40.
  • Show JVM flags with -XX:+PrintFlagsFinal.
  • Java ergonomics: JVM chooses default flag values based on machine classes; i.e., client vs server.
  • Better algorithm and less code almost, including removing dead code, always yields better performance.
  • Death by 1,000 cuts: We may win every battles but will ultimately lose the war. Chrome releases exhibit this behavior—Performance regresses little by little until a “grand improvement” fixes it, and then it regresses again.
  • Don’t prematurely optimize, but also don’t write bad code that is known to be bad for performance.
  • “Thrashing”: Throwing more load into an already overburdened system only makes that system worse. If you optimize a non-bottleneck sub-system, that sub-system will generate more load for the rest of the system, and thus makes overall performance worse. (Thrashing is usually not used in this context, but I can’t think of a better word for this phenomenon.)
  • Occam’s Razor: Start investigating a performance issue from simpler hypothesis (is database slow?) and eventually move to complex one (is it a bug in JVM?).
  • Optimize for the common case.

Chapter 2

  • Test a real application: There is a continuum from microbenchmarks to macrobenchmarks (mesobenchmarks).
  • Microbenchmarks are usually unhelpful.
  • JIT optimizer may cause microbenchmark results useless; so be careful when writing a microbenchmark.
  • Reserve warm-up period for class loader, JIT, memory cache, etc.
  • Measurements:
    • Elapsed time: Time required to perform a certain task, say, sort 1,000 integers.
    • Throughput: Measured by requests per second. Use a zero think time when measure this. Be careful that you might actually measureing the benchmark tool’s throughput.
    • Response time: Use a non-zero think time (usually a constant time?) when measuring this.
  • Give both average and 90% quantile (or 99% quantile if you want) when reporting benchmark results.
  • Use load generator: faban, etc.
  • Use Student’s t-test.
  • Insignificant (inconclusive) but important result vs significant but trivial result—focus on the former.
  • Test early, test often, automate everything, measure everything, and run on the target system.
Creative Commons License
This blog by Che-Liang Chiou is licensed under a Creative Commons Attribution 4.0 International License.