1

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?

ParkNamYoung
  • 31
  • 1
  • 6
  • I think reason is because in Math it is wise to squares than actual numbers. So in end you just adding one with another and apply Sqrt to result. – eocron Feb 03 '17 at 08:46
  • 1
    You also need to "warm up" the JIT first by executing the code you're measuring the performance of. – Anton Gogolev Feb 03 '17 at 08:50
  • 1
    You are comparing apples and oranges. You do not know what the compiler does regarding optimizations of your code ... just to begin with. – Fildor Feb 03 '17 at 08:52
  • I just tried your code, but in a 10000000 times loop. Result: `Vector : 00:00:00.1945984 Sqrt : 00:00:00.1567036` – Pikoh Feb 03 '17 at 08:55
  • 2
    I believe you seriously underestimate what it takes to do performance measures – TaW Feb 03 '17 at 09:07

2 Answers2

2

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);
}
owairc
  • 1,890
  • 1
  • 10
  • 9
1
 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.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536