Java-код
package test;
public class SpeedTest
{
public void first()
{
int num = -500;
int num2 = 0;
while( Math.abs(num) > num2 )
num2 ++;
}
public void second()
{
int num = -500;
int num2 = 0;
num = Math.abs(num);
while( num > num2 )
num2 ++;
}
}
Байт-код
Compiled from "SpeedTest.java"
public class test.SpeedTest extends java.lang.Object{
public test.SpeedTest();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public void first();
Code:
0: sipush -500
3: istore_1
4: iconst_0
5: istore_2
6: goto 12
9: iinc 2, 1
12: iload_1
13: invokestatic #15; //Method java/lang/Math.abs:(I)I
16: iload_2
17: if_icmpgt 9
20: return
public void second();
Code:
0: sipush -500
3: istore_1
4: iconst_0
5: istore_2
6: iload_1
7: invokestatic #15; //Method java/lang/Math.abs:(I)I
10: istore_1
11: goto 17
14: iinc 2, 1
17: iload_1
18: iload_2
19: if_icmpgt 14
22: return
}
Из вышеперечисленного оба они по существу принимают ~ 20 инструкций.Если вы очень разборчивы, то первый - быстрый.
Причина различий в том, что вы вычисляете и сохраняете результат при втором подходе.Который вам нужно снова всплыть при сравнении.В первом случае вы непосредственно сравниваете значение регистра сразу после Math.abs
.И отсюда две дополнительные инструкции.
Обновление As pointed out by @ide and @bestsss:
Количество инструкций в байт-коде на самом деле не коррелирует с количеством их фактического вызова.,Плюс есть HotSpot, чтобы оживить ситуацию (например, оптимизацию мертвого кода).
Как и в этом примере, Math.abs()
вызывается с фиксированным значением -500.Таким образом, HotSpot JVM может оптимизировать его.
Подробнее см. В комментариях ниже.