简体   繁体   中英

Why is the vector.Length faster than Math.sqrt ()?

I have a question about comparing the speed of Vector.Length and Math.sqrt. I used the following code for comparing the speed.

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);

Result :

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

The result shows that Vector.Length is faster than Math.Sqrt() . I think Vector.Length calculates length by using Math.Sqrt() too. then Vector.Length is equal or Slower than Math.Sqrt() . Why is it different from what I think? How Vector.Length is calculated?

Your test is too quick, this is how Vector.Length is defined:

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

and minus operator:

public static Vector operator -(Vector vector1, Vector vector2)
{
    return new Vector(vector1._x - vector2._x, vector1._y - vector2._y);
}
 Vector : 00:00:00.0019342

No, that's far too slow on most any machine. Tells us what you did wrong, you ran the Debug build of your program. Basic counter-measures to ensure you get accurate timing:

  • Build > Configuration Manager > Active solution configuration combobox > select Release
  • Put a for-loop around the code to run the test 10 times, gets rid of startup overhead effects
  • Tools > Options > Debugging > General > untick the "Suppress JIT optimization" checkbox

Output on my lazy laptop:

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

Exactly as fast, like it should be. This measurement is for the x86 jitter, the new x64 jitter released in VS2015 makes Vector.Length less efficient.

As you can tell, the optimizer built into the jitter is very important to get efficient code. It gave Vector.Length the edge in your original test, it got optimized when the .NET Framework was installed on your machine. The job done by NGen.exe. More about what the optimizer does in this answer .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM