我有大量的宏基准测试,它们使用不同的执行引擎(其中一些是多线程的)来测量各种模拟的执行时间。大多数这些作业使用我在抽象基类中指定的 jmh 设置:
@ContextConfiguration(value = AbstractJobExecutorBenchmarker.CONTEXT_LOCATION)
@State(Scope.Benchmark)
@Fork(1)
@BenchmarkMode(Mode.SingleShotTime)
@Warmup(iterations = 1, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 5, timeUnit = TimeUnit.MILLISECONDS)
public abstract class AbstractJobExecutorBenchmarker extends AbstractTestNGSpringContextTests
Run Code Online (Sandbox Code Playgroud)
(我还将 -gc -si false 添加到命令行)
当我启动这些基准测试中的任何一个或一些小的子集时,它都可以正常工作。但是,如果我尝试一次性运行所有这些(即没有过滤选项),jmh 成功地完成了其中的几个,然后在一个特定的基准测试后突然冻结......它的头韵已经完成,最终结果被打印出来,但它看起来不像分叉的JVM被杀死并且新的没有启动,似乎整个过程都被卡住了。打印的最后语句示例:
Iteration 3: 03:59:52.059 [pool-8-thread-1] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.059 [pool-8-thread-3] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.060 [pool-8-thread-5] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.060 [pool-8-thread-6] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-7] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-8] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-9] INFO MessageTrafficController: Starting MessageTrafficController
03:59:52.061 [pool-8-thread-10] …Run Code Online (Sandbox Code Playgroud) 我尝试对我的 Spring(使用 maven)项目的一些方法进行基准测试。我需要在我的项目中的几个字段上使用 @Autowired 和 @Inject。当我运行我的项目时,它运行良好。但是 JMH 总是使用 @Autowired/@Inject 字段获取 NullPointerException。
public class Resources {
private List<Migratable> resources;
@Autowired
public void setResources(List<Migratable> migratables) {
this.resources = migratables;
}
public Collection<Migratable> getResources() {
return resources;
}
}
Run Code Online (Sandbox Code Playgroud)
我的基准课程
@State(Scope.Thread)
public class MyBenchmark {
@State(Scope.Thread)
public static class BenchmarkState {
Resources res;
@Setup
public void prepare() {
res = new Resources();
}
}
@Benchmark
public void testBenchmark(BenchmarkState state, Blackhole blackhole) {
blackhole.consume(state.res.getResources());
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的基准测试时,它在Resources.getResources()
更具体地说是在resources.
它不能自动装配 setResources()。但是如果我运行我的项目(排除基准),它工作正常。
在进行基准测试时,如何使用 …
吞吐量模式给了我 21 ops/ms。所以,我认为一个操作平均需要 1/21 毫秒。然而,平均模式给了我 0.937 ms/op 的分数。如何解释结果?
吞吐量模式:
Result "testMethod":
21.752 ±(99.9%) 0.081 ops/ms [Average]
(min, avg, max) = (20.681, 21.752, 22.529), stdev = 0.344
CI (99.9%): [21.671, 21.834] (assumes normal distribution)
# Run complete. Total time: 00:06:47
Benchmark Mode Cnt Score Error Units
MyBenchmark.testMethod thrpt 200 21.752 ± 0.081 ops/ms
Run Code Online (Sandbox Code Playgroud)
平均模式:
Result "testMethod":
0.937 ±(99.9%) 0.004 ms/op [Average]
(min, avg, max) = (0.890, 0.937, 0.979), stdev = 0.019
CI (99.9%): [0.932, 0.941] (assumes normal distribution)
# Run complete. …Run Code Online (Sandbox Code Playgroud) 我正在使用 JMH 对 DOM 解析器进行基准测试。我得到了非常奇怪的结果,因为第一次迭代实际上比后面的迭代运行得更快
谁能解释为什么会发生这种情况?另外,百分位数和所有数字是什么意思,为什么它在第三次迭代后开始变得稳定?一次迭代是否意味着整个基准测试方法的一次迭代?下面是我正在运行的方法
@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 13, time = 1, timeUnit = TimeUnit.MILLISECONDS)
public void testMethod_no_attr() {
try {
File fXmlFile = new File("500000-6.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
} catch (Exception e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试测量运行基准测试时消耗的内存。我在互联网上发现我可以使用GC分析器来测量它。我试过了,但我不明白答案以及看到消耗的内存量。谁能解释一下结果?谢谢。
MyBenchmark.testMethod_width_2_attribute_text ss 60 32.345 ± 1.759 ms/op
MyBenchmark.testMethod_width_2_attribute_text:·gc.alloc.rate ss 60 26.904 ± 0.217 MB/sec
MyBenchmark.testMethod_width_2_attribute_text:·gc.alloc.rate.norm ss 60 14999630.400 ± 12.578 B/op
MyBenchmark.testMethod_width_2_attribute_text:·gc.churn.PS_Eden_Space ss 60 28.282 ± 15.342 MB/sec
MyBenchmark.testMethod_width_2_attribute_text:·gc.churn.PS_Eden_Space.norm ss 60 15903402.667 ± 8631257.013 B/op
MyBenchmark.testMethod_width_2_attribute_text:·gc.churn.PS_Survivor_Space ss 60 0.654 ± 0.754 MB/sec
MyBenchmark.testMethod_width_2_attribute_text:·gc.churn.PS_Survivor_Space.norm ss 60 368914.667 ± 425374.152 B/op
MyBenchmark.testMethod_width_2_attribute_text:·gc.count ss 60 26.000 counts
MyBenchmark.testMethod_width_2_attribute_text:·gc.time ss 60 105.000 ms
Run Code Online (Sandbox Code Playgroud) 根据 Jackson Streaming API 文档:
如果您明确重写所有转换以使用 Streaming API 而不是数据绑定,您可能能够将吞吐量提高 30-40%;这对实际生成的 JSON 没有任何更改。
阅读全文:https : //github.com/FasterXML/jackson-docs/wiki/Presentation : -Jackson-Performance
但是,根据我的基准测试,在最佳情况下吞吐量提高了 15-20%,对于写入复杂对象,甚至降低了约 23%。
难道我做错了什么?为什么使用流式 api 的复杂对象的写入操作比使用在流式 api 之上工作的 ObjectMapper 慢?
非常有趣的是,对于 java11/12,Jackson Streaming 的写入性能下降更为显着(约 2% 相比于 Java 11/12 的约 24%)。
配置:
JMH 吞吐量结果:
复杂对象
普通对象
结构: …
我想比较直接字节缓冲区(java.nio.ByteBuffer,堆外)和堆缓冲区(通过数组实现)的读取和写入性能。我的理解是,ByteBuffer 在堆外比堆缓冲区至少有两个好处。首先,它不会被 GC 考虑,其次(我希望我做对了)JVM 在读取和写入它时不会使用中间/临时缓冲区。这些优点可能使堆外缓冲区比堆缓冲区更快。如果这是正确的,我不应该期望我的基准显示相同吗?它总是比非堆缓冲区更快地显示堆缓冲区。
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx4G"})
@Warmup(iterations = 3)
@Measurement(iterations = 10)
public class BasicTest {
@Param({"100000"})
private int N;
final int bufferSize = 10000;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(8 * bufferSize);
long buffer[] = new long[bufferSize];
public static void main(String arep[]) throws Exception {
Options opt = new OptionsBuilder()
.include(BasicTest.class.getSimpleName())
.forks(1)
.build();
new Runner(opt).run();
}
@Benchmark
public void offHeapBuffer(Blackhole blackhole) {
IntStream.range(0, bufferSize).forEach(index -> {
byteBuffer.putLong(index, 500 * index);
blackhole.consume(byteBuffer.get(index));
}); …Run Code Online (Sandbox Code Playgroud) 我有两个案例类:addSmall和addBig.
addSmall只包含一个字段。
addBig包含多个字段。
case class AddSmall(set: Set[Int] = Set.empty[Int]) {
def add(e: Int) = copy(set + e)
}
case class AddBig(set: Set[Int] = Set.empty[Int]) extends Foo {
def add(e: Int) = copy(set + e)
}
trait Foo {
val a = "a"; val b = "b"; val c = "c"; val d = "d"; val e = "e"
val f = "f"; val g = "g"; val h = "h"; val i = "i"; …Run Code Online (Sandbox Code Playgroud) 在调查与 Spring 的实例化相关的问题时org.springframework.util.ConcurrentReferenceHashMap(截至spring-core-5.1.3.RELEASE),我使用LinuxPerfAsmProfiler与 JMH 一起提供的工具来分析生成的程序集。
我只是运行这个
@Benchmark
public Object measureInit() {
return new ConcurrentReferenceHashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
JDK 8 上的基准测试允许识别不明显的热点之一:
0.61% 0x00007f32d92772ea: lock addl $0x0,(%rsp) ;*putfield count
; - org.springframework.util.ConcurrentReferenceHashMap$Segment::<init>@11 (line 476)
; - org.springframework.util.ConcurrentReferenceHashMap::<init>@141 (line 184)
15.81% 0x00007f32d92772ef: mov 0x60(%r15),%rdx
Run Code Online (Sandbox Code Playgroud)
这对应于对 volatile 字段的不必要的默认值分配:
0.61% 0x00007f32d92772ea: lock addl $0x0,(%rsp) ;*putfield count
; - org.springframework.util.ConcurrentReferenceHashMap$Segment::<init>@11 (line 476)
; - org.springframework.util.ConcurrentReferenceHashMap::<init>@141 (line 184)
15.81% 0x00007f32d92772ef: mov 0x60(%r15),%rdx
Run Code Online (Sandbox Code Playgroud)
并Segment依次在以下构造函数的循环中实例化CCRHM:
protected final class Segment extends ReentrantLock …Run Code Online (Sandbox Code Playgroud) 我注意到if else/ 三元 ( condition ? a : b) 赋值比ifonly 语句中的条件赋值更快。我在不同的 JDK 上执行了 JMH 基准测试,但我将专注于 JDK 12。
源代码:
@State(Scope.Benchmark)
public class FindMaxBenchmark {
public static int SIZE = 1_000_000;
@Benchmark
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public static void findMax_if(Blackhole bh, Mock mock) {
int result = Integer.MIN_VALUE;
int[] data = mock.tab;
for (int i = 0; i < data.length; i++) {
if (data[i] > result) {
result = data[i];
}
}
bh.consume(result);
}
@Benchmark
@CompilerControl(CompilerControl.Mode.DONT_INLINE)
public static void …Run Code Online (Sandbox Code Playgroud) jmh ×10
java ×8
benchmarking ×3
performance ×3
jvm ×2
assembly ×1
bytebuffer ×1
copy ×1
immutability ×1
jackson ×1
java-11 ×1
maven ×1
profiling ×1
scala ×1
spring ×1