对于我正在编写的小型并发框架,我创建了自己的Thread调度程序,这可以带来巨大的性能提升。对于一个特定的测试55ms而不是87ms(使用ForkJoinPool)运行时间。 但我确实只在jdk 1.8.0_31及更早版本中看到了这个改进。在jdk 1.8.0_40以及后来使用我的调度程序的Benchmark需要250ms,而ForkJoinPool需要230ms。 因此两者的性能都有所下降,但我的优化版本突然比未经优化的版本慢。
这是否在1.8.0_31中引入了任何有意义的改变,这可以解释这种性能的下降?
我阅读了JDK 8u40发行说明,但无法找出导致此问题的原因
其他信息:
经过一些分析(使用可视化虚拟机进行采样)后,我认为以下几行在1.8.0_40然后在1.8.0_31
上慢了很多 public void exec(){
res = fun.invokeWithArguments(args);
}
我发现了这一点,因为在1.8.0_31上,jvisualvm采样器指示13.5%用于exec,13.3%用于generate(这是invokeWithArguments调用的函数)。 在1.8.0_40,jvisualvm采样器表明在执行中花费33.2%,在生成中花费3.6%。 这个数字适用于My Scheduler,但是使用ForkJoinPool它们会显示相同的图片。
有关MethodeHandles的1.8.0_40有什么变化吗?
结论:
我能够在微基准测试中删除invokeWithArguments并用方法调用替换它(遗憾的是,这不可能在基准测试之外,因为目标方法不会是静态的。)
现在结果是一致的,独立于java版本:MyScheduler大约40ms,ForkJoinScheduler大约100ms
我仍然不知道为什么invokeWithArguments有如此巨大的性能下降,如果有人知道它仍然对aswer感兴趣。