原文:Micro Benchmarking with JMH: Measure, don't guess! 作者:Antonio,譯者:Hollis。
許多開發者相信「置 null 助 GC」、「final 內聯提性能」,但 JVM 持續演進,昨天的經驗今日可能失效。判斷代碼效率不應靠猜測,而應建立穩定測試環境,設定性能目標,持續測試驗證。
常見三種 DEBUG 日誌寫法:
logger.debug("Concatenating strings " + x + y + z);
logger.debug("Using variable arguments {} {} {}", x, y, z);
if (logger.isDebugEnabled())
logger.debug("Using if debug enabled {} {} {}", x, y, z);
生產環境日誌級別通常為 INFO/WARN,DEBUG 不輸出,但參數構造成本依然存在。用 JMH 量化三者差異。
mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=org.openjdk.jmh \ -DarchetypeArtifactId=jmh-java-benchmark-archetype \ -DarchetypeVersion=1.4.1 \ -DgroupId=org.agoncal.sample.jmh -DartifactId=logging -Dversion=1.0
生成項目含 pom.xml(含 maven-shade-plugin)與空 MyBenchmark 類。打包運行:
mvn clean install java -jar target/benchmarks.jar
JMH 自動預熱、迭代,輸出 ops/sec(每秒操作數),數值越大性能越好。
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.7</version></dependency> <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.0.11</version></dependency>
配置 logback.xml 級別為 INFO。
@Benchmark public void testConcatenatingStrings() { ... logger.debug("Concatenating strings " + x + y + z); }
@Benchmark public void testVariableArguments() { ... logger.debug("Variable arguments {} {} {}", x, y, z); }
@Benchmark public void testIfDebugEnabled() { ... if (logger.isDebugEnabled()) logger.debug("If debug enabled {} {} {}", x, y, z); }
| 迭代 | 字符串拼接 | 變量參數 | if 判斷 |
|---|---|---|---|
| Average | 57,491 | 99,227 | 104,913 |
結論:isDebugEnabled 性能最佳,但 變量參數 兼顧可讀性與性能(無樣板代碼),推薦生產環境使用變量參數形式。
JVM 十年巨變,舊優化模式不可盲信。JMH 讓微基準測試簡單高效,是性能分析的第一步。完整示例見 JMH Samples。