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

时间:2017-02-03 08:41:45

标签: c# performance math vector

我有一个关于比较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.Length也会使用Math.Sqrt()计算长度。然后Vector.Length等于或慢于Math.Sqrt()。 为什么它与我的想法有所不同?如何计算Vector.Length?

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

 Vector : 00:00:00.0019342

不,这对大多数机器来说都太慢了。告诉我们你做错了什么,你运行了程序的Debug版本。确保准确计时的基本对策:

  • 构建&gt;配置管理器&gt; <有源解决方案配置组合框>选择发布
  • 在代码周围放置for循环以运行测试10次,摆脱启动开销效应
  • 工具&gt;选项&gt;调试&gt;一般&gt;取消勾选“抑制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中执行的操作的更多信息。