我如何确定编译器不会优化我的性能测试? [英] How can I be sure that the compiler doesn't optimize away my performance test?

查看:54
本文介绍了我如何确定编译器不会优化我的性能测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类会做一些耗时的计算.我正在尝试对其进行性能测试:

I have a class that does some time-consuming calculations. I'm trying to performance test it:

int numValues = 1000000;
Random random = new Random();
startMeasuringTime();
double result;
for (int i = 0; i < numValues; i++) {
    result = calculatorInstance.doSomeTimeConsumingCalculationsOn(random.nextDouble());
}
stopMeasuringTime();

我使用的是随机值,因此编译器不会优化一百万次相同的计算.但是结果呢?编译器是否看到它不再被使用并忽略调用(但是,它可以看到方法调用可能产生的任何副作用吗?)

I'm using random values so the compiler won't optimize the calculations for being a million times the same. But what about the results? Does the compiler see it isn't used any more and leaves out the call (but then, can it see any side effects the method call could have?)

我不想将结果放在某处(放入文件、数组或 System.out),因为我认为这会因我不想测量的工作而减慢测试速度.或者产生 OutOfMemoryError.

I don't want to put the results somewhere (into a file, array or to System.out), because I think this will slow down the test with work that I don't want to measure. Or produce an OutOfMemoryError.

提前致谢.

稍微更改了标题

推荐答案

但是结果呢?编译器是否看到它不再被使用并忽略调用(但是,它可以看到方法调用可能产生的任何副作用吗?)

But what about the results? Does the compiler see it isn't used any more and leaves out the call (but then, can it see any side effects the method call could have?)

这取决于.如果 JIT 编译器可以检测到方法调用没有副作用,那么它有权将其优化掉.特别是因为未使用结果值.在这种情况下,您可能只是测量对 random.nextDouble() 的调用......或者可能是一个空循环.

It depends. If the JIT compiler can detect that the method call has no side-effects, then it is entitled to optimize it away. Especially since the result value is not used. In this case, you might just be measuring the calls to random.nextDouble() ... or possibly an empty loop.

为了确保它不能被优化掉,你应该这样写:

To be sure you should it cannot be optimized away, you should probably write it like this:

int numValues = 1000000;
Random random = new Random();
startMeasuringTime();
double result;
for (int i = 0; i < numValues; i++) {
    result = result +
        calculatorInstance.doSomeCalculationsOn(random.nextDouble());
}
stopMeasuringTime();
System.err.println(result);  // Force result to be computed.

(我假设耗时的计算确实取决于参数...)

(I'm assuming that the time consuming calculation does depend on the argument ...)

还需要考虑JVM预热;即在 JVM 中多次运行该基准代码,直到测量的时间稳定.

You also need to take JVM warmup into account; i.e. run that benchmark code multiple times in the JVM until the measured time stabilizes.

说编译器过度优化"是错误的.编译器实际上正确地完成了它的工作.如果有的话,问题出在您的代码中;即它没有任何用处".

Saying that the compiler is "over-optimizing" is kind of wrong. The compiler is actually doing its job correctly. If anything, the fault is in your code; i.e. it does "nothing useful".

这篇关于我如何确定编译器不会优化我的性能测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆