2017-02-03 11 views
1

私は、Vector.LengthとMath.sqrtの速度を比較することに関して質問があります。 速度を比較するために次のコードを使用しました。なぜvector.LengthはMath.sqrt()より速いのですか?

int cnt = 100000; 
double result = 0; 
Vector A = new Vector(1.342,2.0); 
Vector B = new Vector(5.1234,2.0); 
Stopwatch sw = new Stopwatch(); 

sw.Start(); 
while(cnt-- > 1) 
{ 
    Vector AB = A-B; 
    result = AB.Length; 
} 
sw.Stop(); 
System.Console.WriteLine("Vector : " + sw.Elapsed); 
sw.Reset(); 

cnt = 100000; 
sw.Start(); 
while(cnt-- >1) 
{ 
result = Math.Sqrt((B.X-A.X)*(B.X-A.X)+(B.Y-A.Y)*(B.Y-A.Y)); 
} 
sw.Stop(); 
System.Console.WriteLine("Sqrt : " + sw.Elapsed); 

結果:

Vector : 00:00:00.0019342 
Sqrt : 00:00:00.0041913 

結果はVector.LengthMath.Sqrt()よりも高速であることを示しています。 Vector.LengthMath.Sqrt()でも長さを計算すると思います。 Vector.LengthMath.Sqrt()と等しいか遅いです。 なぜ私の考えと違うのですか? Vector.Lengthの計算方法は?

+0

私は、数学では実際の数よりも正方形であることが賢明だからだと思います。だから最後にあなたは別のものを追加し、結果にSqrtを適用します。 – eocron

+1

パフォーマンスを測定しているコードを実行して、JITを最初に "ウォームアップ"する必要があります。 –

+1

あなたはリンゴとオレンジを比較しています。コンパイラがコードの最適化に関して何をしているのかわかりません。 – Fildor

答えて

1
Vector : 00:00:00.0019342 

いいえ、それはほとんどの任意のマシン上であまりにも遅いです。あなたが間違っていたことを教えてください。プログラムのDebugビルドを実行しました。あなたが正確なタイミングを得ることを確認するための基本的な対策:

  • ビルド]> [構成マネージャ]> [アクティブソリューション構成コンボボックス>テストを10回実行するコードの周りforループ入れ
  • をリリース選択し、取り除きます私の怠惰なラップトップ上で起動オーバーヘッドの影響
  • ツール]> [オプション]> [デバッグ>一般> "JITの最適化を抑止する" のチェックボックスに

を外します出力:

Vector : 00:00:00.0000975 
Sqrt : 00:00:00.0000917 
Vector : 00:00:00.0000912 
Sqrt : 00:00:00.0000917 
Vector : 00:00:00.0000917 
Sqrt : 00:00:00.0000917 
Vector : 00:00:00.0000912 
... etc 

正確に速く、そうすべきです。この測定はx86ジッタのため、VS2015でリリースされた新しいx64ジッタはVector.Lengthの効率を低下させます。

ジッタに組み込まれているオプティマイザは、効率的なコードを得るためには、非常にであることがわかります。 Vector.Lengthは、.NET Frameworkがマシンにインストールされたときに最適化された元のテストでエッジを与えました。ジョブはNGen.exeによって実行されました。オプティマイザの詳細については、this answerを参照してください。

2

あなたのテストはこれがVector.Lengthが定義されている方法で、あまりにも速いです:

public double Length 
{ 
    get 
    { 
     return Math.Sqrt((this._x * this._x) + (this._y * this._y)); 
    } 
} 

とマイナス演算子:

public static Vector operator -(Vector vector1, Vector vector2) 
{ 
    return new Vector(vector1._x - vector2._x, vector1._y - vector2._y); 
} 
関連する問題