2011-06-28 21 views
2

リンク:http://download.oracle.com/javase/6/docs/api/java/lang/Long.html#numberOfTrailingZeros%28long%29Long.numberOfTrailingZerosのJava実装()

ここでは、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型と2つの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.私はWindows 7 64ビットを使用しているので、元の実装は32ビットシステムで高速かもしれません。少なくとも、Javaは自分のx64 sdkで自分のバージョンのようなものを使うべきです。何か案は?

+2

彼らはどこでも動作するコードを書いている、とどこか特定のパフォーマンスの低下を被るべきではありません。異なるバージョンのコードを別々のプラットフォーム(たとえ32対64ビット)で出荷したいのであれば、それらを固有の方法にして適切に最適化することができます。 –

+1

これは、マイクロベンチマークの結果が再現可能であると仮定すると、** 0.33%**のパフォーマンスが向上します(一般的には疑問視されています...)。オラクルがあなたの努力に敬意を表してくれることを強く疑う。 –

+0

:)ええ、私はこの機能を多く使うチェスエンジンを書いています。 – functionptr

答えて

3

パフォーマンスの差は0.5パーセントですが、ほぼすべてのアプリケーションで無視できます。この1つの方法でピーク性能が必要な1つのアプリケーションで作業する場合は、自分で実装することができます。

+1

+1:2つの関数をテストする順序を変更するか、使用する値によってこれ以上の違いが生じます。 –

+0

@Peter:それぞれ10個のテストを行い、平均して – functionptr

+0

@Functionであるため、テストを少なくとも5秒間実行してから各機能を試してみる必要があります。私はそれが約100万倍以上になると思う。 –