А как насчет результатов? Видит ли компилятор, что он больше не используется, и пропускает вызов (но может ли он увидеть какие-либо побочные эффекты, которые может иметь вызов метода?)
Это зависит. Если JIT-компилятор может обнаружить, что вызов метода не имеет побочных эффектов, он имеет право его оптимизировать. Тем более что значение результата не используется. В этом случае вы можете просто измерять вызовы на random.nextDouble()
... или, возможно, на пустой цикл.
Чтобы быть уверенным, что он не может быть оптимизирован, вы должны написать это так:
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.
(Я предполагаю, что длительный расчет зависит от аргумента ...)
Вам также необходимо принять во внимание прогрев JVM; то есть запускать этот эталонный код несколько раз в JVM, пока измеренное время не стабилизируется.
Сказать, что компилятор "чрезмерно оптимизирует", является своего рода ошибкой. Компилятор фактически делает свою работу правильно. Во всяком случае, ошибка в вашем коде; то есть "ничего полезного" не происходит.