欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JVM Benchmark - 严肃向

程序员文章站 2022-03-07 14:12:42
...

JVM Benchmark - 严肃向

前些天看到了一个同事写的问题分析分享,他从服务的性能打点中得出Jackson性能比较差,并自己做实验得出了Jackson比org.json效率更低的结论。对他的代码稍做分析发现同事对写Benchmark还是有一些误解,结论分析也还是太过于草率。

我深信Benchmark是有讲究的,要写出有意义有说服力的Benchmark是要严肃的。

1. 什么是Benchmark

Testing: 确保部分程序的表现是符合预期的(一般是输出正确/错误)

Benchmarking: 计算部分程序的性能(Performance)指标(产出是个连续值)

影响性能的因素:

  • 处理器的速度
  • 处理器的核数(并发性能)
  • 内存访问速度和吞吐量
  • 缓存访问模式
  • 程序运行时开销(垃圾回收GC,运行时编译JIT ,线程调度)

评估方法(Statistically Rigorous Java Performance Evaluation)——首先把性能当作随机变量,再用上统计方法:

  1. 多次重复(比如10万+)
  2. 统计量(平均值与方差)
  3. 去掉异常值
  4. 确保稳定的状态(预热)
  5. 避免异常情况(GC,JIT)

为什么要预热 Warmup?因为JVM程序在启动后需要经历一段时间的预热步骤,包括:

  1. 解释代码
  2. 部分程序被编译成机器码
  3. JVM可能做一些额外优化
  4. 程序达到一个稳定状态

这些步骤会显著提升首次执行的时间,需要排除掉。

2. Json序列化/反序列化 Benchmark

2.1 测试需要关注的点

回到Json序列化和反序列化的问题,严谨一点应该:

  1. 交待机器配置(一般只需要交待CPU和内存)
  2. 重复次数可观(10~100万)
  3. 区分Json(反)序列化是到Java Bean,还是完成相应库的内部结构表达
  4. 需要在不同的负载(字符串的大小)下进行测试
  5. 需要在简单的单层以及多层嵌套结构下分别测试
  6. 进行预热

2.2 使用测试框架

合理使用测试框架可以轻松完成2.1中提到的点,只是一点参数设置而已。

JMH

JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targetting the JVM.

OpenJDK发布的代码工具,不需要使用OpenJDK,加入下面的依赖即可使用。

"org.openjdk.jmh" % "jmh-generator-annprocess" % "1.21" 
"org.openjdk.jmh" % "jmh-core" % "1.21"

如果是Scala的代码,也可以使用ScalaMeter。

ScalaMeter

ScalaMeter is a microbenchmarking and performance regression testing framework for the JVM platform that allows expressing performance tests in a way which is both simple and concise.
It can be used both from Scala and Java.

  • write performance tests in a DSL similar to ScalaTest and ScalaCheck
  • specify test input data
  • specify how test results are collected
  • organize performance tests hierarchically
"com.storm-enroute" %% "scalameter" % "0.18"

使用示例略过,两个包使用起来都非常简单。

2.3 回到Json序列化反序列化Benchmark

本来想做一个示例项目,看了fabienrenaud/java-json-benchmark这个项目后就放弃了,代码/数据图表都有,需要自取。Json库哪家强?这个不重要,方法论才是目标。

3. 小结

Benchmark是要给别人看的,要少给人口舌的余地的话只有更严谨。前段时间做了一个基于JMH的Benchmark,看看有什么槽点?

JVM Benchmark - 严肃向

最后,开头提到的同事分析的Jackon的问题成立吗?不一定,真实环境总是复杂的,比如在Full GC发生的时候,所有操作的时间都会拉长。严谨一点应该是定位到“有问题”的点,消除环境上的差异,单纯地再做一次这一条耗时长的数据的重复十万次解析,问题自然明了。

相关标签: 杂谈