Основываясь на обсуждениях вокруг ответа на этот вопрос, я обнаружил действительно странное поведение оптимизатора Java Hotspot. Наблюдаемое поведение, по крайней мере, можно увидеть в Oracle VM 1.7.0_17, но, похоже, оно встречается и в более старых версиях Java 6.
Прежде всего, я уже знал, что оптимизатор, очевидно, осознает, что некоторые методы в стандартном API являются инвариантными и не имеют побочных эффектов. При выполнении цикла, такого как double x=0.5; for(double d = 0; d < Math.sin(x); d += 0.001);
, выражение Math.sin(x)
не оценивается для каждой итерации, но оптимизатор знает, что метод Math.sin
не имеет соответствующих побочных эффектов и что результат является инвариантным, пока x
не изменяется в цикле.
Теперь я заметил, что простое изменение x
от 0.5 до 1.0 отключает эту оптимизацию. Дальнейшие тесты показывают, что оптимизация разрешена только в том случае, если abs (x) ASIN (1/SQRT (2)). Есть ли веская причина для этого, чего я не вижу, или это лишнее ограничение оптимизационных условий?
Изменить: оптимизация, похоже, реализована в hotspot/src/share/vm/opto/subnode.cpp