下面是一个简单的程序,只需稍作改动,就会对性能产生重大影响,我不明白为什么。
该程序所做的并不真正相关,但它通过计算两个不同质量的物体与墙壁之间的碰撞以非常复杂的方式计算 PI。当我改变代码时,我注意到性能上有很大的差异。
有问题的行是数学上等价的注释行。使用慢速版本使整个程序花费的时间大约是使用快速版本的两倍。
int iterations = 0;
for (int i = 4; i < 9; i++)
{
Stopwatch s = Stopwatch.StartNew();
double ms = 1.0;
double mL = Math.Pow(100.0, i);
double uL = 1.0;
double us = 0.0;
double msmLInv = 1d / (ms + mL);
long collisions = 0;
while (!(uL < 0 && us <= 0 && uL <= us))
{
Debug.Assert(++iterations > 0);
++collisions;
double vs = (2 * mL * uL + us * (ms - mL)) * msmLInv;
//double vL = (2 * ms * us - uL * (ms - mL)) * msmLInv; //fast
double vL = uL + (us - vs) / mL; //slow
Debug.Assert(Math.Abs(((2 * ms * us - uL * (ms - mL)) * msmLInv) - (uL + (us - vs) / mL)) < 0.001d); //checks equality between fast and slow
if (vs > 0)
{
++collisions;
vs = -vs;
}
us = vs;
uL = vL;
}
s.Stop();
Debug.Assert(collisions.ToString() == "314159265359".Substring(0, i + 1)); //check the correctness
Console.WriteLine($"i: {i}, T: {s.ElapsedMilliseconds / 1000f}, PI: {collisions}");
}
Debug.Assert(iterations == 174531180); //check that we dont skip loops
Console.Write("Waiting...");
Console.ReadKey();
我的直觉说,因为快速版本有 7 个操作,而慢版本有 4 个操作,所以慢版本应该更快,但事实并非如此。
我使用 .NET Reflector 对程序进行了反汇编,结果显示它们大部分是相同的,正如预期的那样,除了下面显示的部分。前后的代码相同
//slow
ldloc.s uL
ldloc.2
ldloc.s us
ldloc.s vs
sub
mul
ldloc.3
div
add
犯罪嫌疑人X
跃然一笑
相关分类