Performance Java-重复的函数调用减少了执行时间
我有以下代码Performance Java-重复的函数调用减少了执行时间,performance,jvm,java-8,java-stream,Performance,Jvm,Java 8,Java Stream,我有以下代码 public class BenchMark { public static void main(String args[]) { doLinear(); doLinear(); doLinear(); doLinear(); } private static void doParallel() { IntStream range = IntStream.range(
public class BenchMark {
public static void main(String args[]) {
doLinear();
doLinear();
doLinear();
doLinear();
}
private static void doParallel() {
IntStream range = IntStream.range(1, 6).parallel();
long startTime = System.nanoTime();
int reduce = range
.reduce((a, item) -> a * item).getAsInt();
long endTime = System.nanoTime();
System.out.println("parallel: " +reduce + " -- Time: " + (endTime - startTime));
}
private static void doLinear() {
IntStream range = IntStream.range(1, 6);
long startTime = System.nanoTime();
int reduce = range
.reduce((a, item) -> a * item).getAsInt();
long endTime = System.nanoTime();
System.out.println("linear: " +reduce + " -- Time: " + (endTime - startTime));
}
}
我试图对流进行基准测试,但在一次又一次调用同一个函数时,执行时间稳步减少
输出:
linear: 120 -- Time: 57008226
linear: 120 -- Time: 23202
linear: 120 -- Time: 17192
linear: 120 -- Time: 17802
Process finished with exit code 0
第一次和第二次执行时间之间存在巨大差异
我相信JVM可能在幕后做了一些把戏,但有人能帮我理解那里到底发生了什么吗
是否有任何方法可以避免这种优化,以便我可以基准测试真正的执行时间?更新:请参阅@Marko的答案,了解lambda链接导致的初始延迟的解释
第一次调用的执行时间较长可能是由于错误。简而言之,在第一次调用方法时,会将字节码JIT编译为本机代码。JVM然后尝试通过识别频繁调用的(热)方法进行进一步优化,并重新生成它们的代码以获得更高的性能 是否有任何方法可以避免这种优化,以便我可以基准测试真正的执行时间 您当然可以通过排除前几个结果来解释JVM初始预热。然后在数万次迭代的循环中增加对方法的重复调用次数,并平均结果
<> P>有更多的选项,您可能需要考虑添加到您的执行中来帮助减少噪声,如本文中所讨论的。这也有一些很好的提示。更新:关于lambda链接导致的初始延迟的解释,请参考@Marko的答案
第一次调用的执行时间较长可能是由于错误。简而言之,在第一次调用方法时,会将字节码JIT编译为本机代码。JVM然后尝试通过识别频繁调用的(热)方法进行进一步优化,并重新生成它们的代码以获得更高的性能 是否有任何方法可以避免这种优化,以便我可以基准测试真正的执行时间 您当然可以通过排除前几个结果来解释JVM初始预热。然后在数万次迭代的循环中增加对方法的重复调用次数,并平均结果
<> P>有更多的选项,您可能需要考虑添加到您的执行中来帮助减少噪声,如本文中所讨论的。这也有一些很好的提示。JavaVM在第一次使用类时将类加载到内存中。
因此,第一次运行和第二次运行之间的差异可能是由类加载引起的。JavaVM在第一次使用类时将类加载到内存中。 因此,第一次和第二次运行之间的差异可能是由类加载引起的 我相信JVM可能在幕后做了一些把戏,但有人能帮我理解那里到底发生了什么吗
invokedynamic
调用站点)-Xint
传递到java
命令。还有更多的标志用于禁用优化的各个方面
我相信JVM可能在幕后做了一些把戏,但有人能帮我理解那里到底发生了什么吗
invokedynamic
调用站点)-Xint
传递到java
命令。还有更多的标志用于禁用优化的各个方面
真实执行时间
没有“真正的执行时间”这样的东西。如果您只需要解决此任务一次,那么真正的执行时间将是第一次测试的时间(以及启动JVM本身的时间)。通常,执行给定代码所花费的时间取决于许多因素:
- 无论这段代码是解释的,JIT都是由C1或C2编译器编译的。请注意,不仅仅有三个选项。如果从另一个方法调用一个方法,其中一个可能会被解释,另一个可能会被编译
- 对于C2编译器:这段代码以前是如何执行的,那么分支和类型概要文件中有什么内容呢。波尔