昨日、なぜMath.pow(int,int)
こんなに遅いのかという質問を見ましたが、言葉が貧弱で研究努力も見られなかったので、すぐに締め切られました。
私は自分で少しテストを行ったところMath.pow
、整数引数を処理するときに、メソッドが実際に自分のナイーブな実装(特に効率的な実装でさえない)と比較して非常に遅く実行されることがわかりました。以下は、これをテストするために実行したコードです。
class PowerTest {
public static double myPow(int base, int exponent) {
if(base == 0) return 0;
if(exponent == 0) return 1;
int absExponent = (exponent < 0)? exponent * -1 : exponent;
double result = base;
for(int i = 1; i < absExponent; i++) {
result *= base;
}
if(exponent < 1) result = 1 / result;
return result;
}
public static void main(String args[]) {
long startTime, endTime;
startTime = System.nanoTime();
for(int i = 0; i < 5000000; i++) {
Math.pow(2,2);
}
endTime = System.nanoTime();
System.out.printf("Math.pow took %d milliseconds.\n", (endTime - startTime) / 1000000);
startTime = System.nanoTime();
for(int i = 0; i < 5000000; i++) {
myPow(2,2);
}
endTime = System.nanoTime();
System.out.printf("myPow took %d milliseconds.\n", (endTime - startTime) / 1000000);
}
}
私のコンピューター(Intel x86_64 cpu上のLinux)では、ほとんどの場合、出力には10ミリ秒かかり、2ミリ秒Math.pow
かかると報告されていましたmyPow
。これは時々ミリ秒単位で変動しましたが、平均Math.pow
して約5倍遅くなりました。
私はいくつかの研究を行なったし、によるとgrepcode、Math.pow
唯一の型シグネチャを持つメソッドを提供しています(double, double)
、そしてそれはにそれを延期StrictMath.pow
ネイティブメソッド呼び出しである方法。
Math
ライブラリpow
がdoubleを処理する関数のみを提供しているという事実は、この質問に対する可能な答えを示しているようです。明らかに、double型の底または指数の可能性を処理する必要があるべき乗アルゴリズムは、整数のみを処理する私のアルゴリズムよりも実行に時間がかかります。ただし、最終的には、アーキテクチャに依存するネイティブコード(ほとんどの場合、JVMバイトコード(私の場合はCまたはアセンブリ)よりも高速に実行されます)に要約されます。このレベルでは、データ型をチェックし、可能であればより単純なアルゴリズムを実行するために最適化が行われるようです。
この情報を考えると、整数引数が与えられたときに、ネイティブMath.pow
メソッドが最適化されていないナイーブなmyPow
メソッドよりも一貫してはるかに遅く実行されるのはなぜですか?
他の人が言っているようにdouble
、浮動小数点演算はほぼ確実に遅くなるため、の使用を無視することはできません。ただし、これが唯一の理由ではありません。実装を変更してそれらを使用する場合でも、より高速です。
これは、の二つである:最初にそれである2^2
(指数ではなく、XOR)を実行するために非常に速い計算がある、あなたのアルゴリズムはそのために使用する結構ですので-から2つの値を使用してみてくださいRandom#nextInt
(またはnextDouble
)、あなたはそれが表示されますMath#pow
ですが、実際にははるかに高速です。
もう1つの理由は、ネイティブメソッドの呼び出しにはオーバーヘッドがあり、2^2
計算が非常に速くMath#pow
、何度も呼び出すため、ここでは実際に意味があります。JNI呼び出しが遅くなる理由を参照してください。詳細については。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加