简体   繁体   English

为什么vector.Length比Math.sqrt()快?

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

I have a question about comparing the speed of Vector.Length and Math.sqrt. 我有一个关于比较Vector.Length和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() . 结果显示Vector.LengthMath.Sqrt()快。 I think Vector.Length calculates length by using Math.Sqrt() too. 我认为Vector.Length通过使用Math.Sqrt()来计算长度。 then Vector.Length is equal or Slower than Math.Sqrt() . 然后Vector.Length等于或慢于Math.Sqrt() Why is it different from what I think? 为什么它与我的想法有所不同? How Vector.Length is calculated? 如何计算Vector.Length?

Your test is too quick, this is how Vector.Length is defined: 您的测试太快了,这就是Vector.Length的定义方式:

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. 告诉我们你做错了什么,你运行了程序的Debug版本。 Basic counter-measures to ensure you get accurate timing: 确保准确计时的基本对策:

  • Build > Configuration Manager > Active solution configuration combobox > select Release Build> Configuration Manager> Active solution configuration combobox>选择Release
  • Put a for-loop around the code to run the test 10 times, gets rid of startup overhead effects 在代码周围放一个for循环来运行测试10次,摆脱启动开销效应
  • Tools > Options > Debugging > General > untick the "Suppress JIT optimization" checkbox 工具>选项>调试>常规>取消选中“抑制JIT优化”复选框

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. 此测量用于x86抖动,VS2015中发布的新x64抖动使Vector.Length效率降低。

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. 它为您的原始测试提供了Vector.Length优势,在您的计算机上安装了.NET Framework后,它得到了优化。 The job done by NGen.exe. 这项工作由NGen.exe完成。 More about what the optimizer does in this answer . 更多关于优化器在此答案中的作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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