2011-06-28 42 views
2

鏈接到文件:http://download.oracle.com/javase/6/docs/api/java/lang/Long.html#numberOfTrailingZeros%28long%29Java實現Long.numberOfTrailingZeros()

這裏是Java實現的源代碼:

/** 
* Returns the number of zero bits following the lowest-order ("rightmost") 
* one-bit in the two's complement binary representation of the specified 
* <tt>long</tt> value. Returns 64 if the specified value has no 
* one-bits in its two's complement representation, in other words if it is 
* equal to zero. 
* 
* @return the number of zero bits following the lowest-order ("rightmost") 
*  one-bit in the two's complement binary representation of the 
*  specified <tt>long</tt> value, or 64 if the value is equal 
*  to zero. 
* @since 1.5 
*/ 
public static int numberOfTrailingZeros(long i) { 
    // HD, Figure 5-14 
int x, y; 
if (i == 0) return 64; 
int n = 63; 
y = (int)i; if (y != 0) { n = n -32; x = y; } else x = (int)(i>>>32); 
y = x <<16; if (y != 0) { n = n -16; x = y; } 
y = x << 8; if (y != 0) { n = n - 8; x = y; } 
y = x << 4; if (y != 0) { n = n - 4; x = y; } 
y = x << 2; if (y != 0) { n = n - 2; x = y; } 
return n - ((x << 1) >>> 31); 
} 

該算法將長成兩個整數,並處理每一個int類型。我的問題是爲什麼不使用y = x < < 32而不是打破長距離?

這裏是我的版本:

public static int bit(long i) 
{ 
    if (i == 0) return 64; 
    long x = i; 
    long y; 
    int n = 63; 
    y = x << 32; if (y != 0) { n -= 32; x = y; } 
    y = x << 16; if (y != 0) { n -= 16; x = y; } 
    y = x << 8; if (y != 0) { n -= 8; x = y; } 
    y = x << 4; if (y != 0) { n -= 4; x = y; } 
    y = x << 2; if (y != 0) { n -= 2; x = y; } 
    return (int) (n - ((x << 1) >>> 63)); 
} 

我測試了這兩種方法,取平均值。執行時間:595,我的版本時間:593。也許最初的實現在32位系統上更快,因爲我使用的是Windows 7 64位。至少Java應該在他們的x64 sdk中使用類似我的版本的東西。有任何想法嗎?

+2

他們已經寫了作品無處不在的代碼,並且不應該在任何地方遭受特定的性能損失。如果他們想在不同的平臺上發佈不同版本的代碼,即使只有32位和64位,那麼他們也可以使它成爲本地方法並正確優化它。 –

+1

這是一個** 0.33%**的性能提升 - 假設microbenchmarking結果是可重現的(通常需要質疑...)。我強烈懷疑oracle會尊重你的努力... –

+0

:)是的,我正在寫一個使用這個函數的棋子引擎。 – functionptr

回答

3

幾乎每個應用程序都可以忽略0.5%的性能差異。如果您使用這種單一方法需要查看性能的應用程序,則可以自行實施。

+1

+1:更改您測試兩個函數或您使用的值的順序可以使這個更大的區別。 –

+0

@彼得:我測試了10個,平均值爲 – functionptr

+0

@功能,您需要運行測試至少5秒,首先嚐試每個功能。我懷疑這將是大約一百萬次或更多。 –