我試圖剖析一些代碼,但我遇到了一些問題,我認爲Java的編譯器很聰明並且改變了代碼的工作方式。性能分析方法性能
例如方法:
public int method1(int bits)
{
// seed is a long object field
seed = seed * 0x5DEECE66DL + 0xBL & (1L << 48) - 1;
return (int) (seed >>> 48 - bits);
}
public int method2(int bits)
{
// seed is a long object field
seed *= 0x5DEECE66DL;
seed += 0xBL & (1L << 48) - 1;
return (int) (seed >>> 48 - bits);
}
public int method3(int bits)
{
// multiplier, seeds, n, and carry are long/long array object fields
final long t = multiplier * seeds[n] + carry;
// carry = t/b (done in an unsigned way)
final long div32 = t >>> 32; // div32 = t/(b+1)
carry = div32 + ((t & 0xFFFFFFFFL) >= 0xFFFFFFFFL - div32 ? 1L : 0L);
// seeds[n] = (b-1)-t%b (done in an unsigned way)
seeds[n] = 0xFFFFFFFEL - (t & 0xFFFFFFFFL) - (carry - div32 << 32) - carry & 0xFFFFFFFFL;
final long result = seeds[n];
n = n + 1 & r - 1;
return (int) (result >>> 32 - bits);
}
現在,比較性能,我使用該測試臺:
// gen is the object containing the methods/fields
int result;
long start = System.currentTimeMillis();
for (int i = 0; i < 0x7FFFFFFF; ++i)
{
result = gen.method1(32);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
for (int i = 0; i < 0x7FFFFFFF; ++i)
{
result = gen.method2(32);
}
end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
for (int i = 0; i < 0x7FFFFFFF; ++i)
{
result = gen.method3(32);
}
end = System.currentTimeMillis();
System.out.println(end - start);
不過,我找回結果是相當奇怪:
7 3109 13402
method1
和method2
的計算時間應該與計算完全相同的計算時間大致相同。 method3
我可以理解需要更長時間,但看看計算量,3個結果中沒有一個對我來說足夠長。這似乎標誌着我以某種方式Java的優化我的測試平臺,而不是全部運行0x7FFFFFFF
次。
爲了解決這個問題,我想聲明result
作爲static volatile
場(試驗檯法外),以及這樣做產生可信的結果:
21814 21468 26962
現在的問題是這是公認的如何配置方法?我仍然希望優化發生在我正在分析的方法中,而不是在測試平臺中(至少不會導致該方法被調用的次數少於指定次數或在運行之間緩存結果的優化)。
問題的javap -v在你的類以查看編譯器做什麼不同。我認爲這種差異將會是一個額外的LLOAD和LSTORE操作(完成0x7FFFFFFF次)。 – MeBigFatGuy 2011-04-26 02:14:34
我看到的唯一區別是在結果的聲明行中,無論是靜態的還是靜態的和易失性的。 Diff:' - 靜態int結果; + static volatile int result; public static void main(java.lang.String [])' – helloworld922 2011-04-26 02:33:21