Ответ 1
JMH - хороший инструмент, но все еще не идеальный.
Конечно, нет никакой разницы в скорости между возвратом 0, 1 или любым другим целым числом. Однако имеет значение, как значение потребляется JMH и как это компилируется HotSpot JIT.
Чтобы предотвратить оптимизацию вычислений JIT, JMH использует специальный класс Blackhole для использования значений, возвращаемых из теста. Ниже приведено значение для целых значений:
public final void consume(int i) {
if (i == i1 & i == i2) {
// SHOULD NEVER HAPPEN
nullBait.i1 = i; // implicit null pointer exception
}
}
Здесь i
- это значение, возвращаемое из теста. В вашем случае это либо 0, либо 1. Когда i == 1
условие никогда не будет выполнено как if (1 == i1 & 1 == i2)
, которое скомпилировано следующим образом:
0x0000000002b4ffe5: mov 0xb0(%r13),%r10d ;*getfield i1
0x0000000002b4ffec: mov 0xb4(%r13),%r8d ;*getfield i2
0x0000000002b4fff3: cmp $0x1,%r8d
0x0000000002b4fff7: je 0x0000000002b50091 ;*return
Но когда i == 0
JIT пытается "оптимизировать" два сравнения с 0
с помощью инструкций setne
. Однако код результата становится слишком сложным:
0x0000000002a40b28: mov 0xb0(%rdi),%r10d ;*getfield i1
0x0000000002a40b2f: mov 0xb4(%rdi),%r8d ;*getfield i2
0x0000000002a40b36: test %r10d,%r10d
0x0000000002a40b39: setne %r10b
0x0000000002a40b3d: movzbl %r10b,%r10d
0x0000000002a40b41: test %r8d,%r8d
0x0000000002a40b44: setne %r11b
0x0000000002a40b48: movzbl %r11b,%r11d
0x0000000002a40b4c: xor $0x1,%r10d
0x0000000002a40b50: xor $0x1,%r11d
0x0000000002a40b54: and %r11d,%r10d
0x0000000002a40b57: test %r10d,%r10d
0x0000000002a40b5a: jne 0x0000000002a40c15 ;*return
То есть медленнее return 0
объясняется больше инструкций ЦП, выполненных в Blackhole.consume()
.
Примечание для разработчиков JMH: Я бы предложил переписать Blackhole.consume
как
if (i == l1) {
// SHOULD NEVER HAPPEN
nullBait.i1 = i; // implicit null pointer exception
}
где volatile long l1 = Long.MIN_VALUE
. В этом случае условие всегда будет всегда ложным, но оно будет скомпилировано одинаково для всех возвращаемых значений.