早上好,下午或晚上,
直到今天,我认为比较是基本的处理器指令之一,因此它是计算机中最快的操作之一...另一方面,我知道乘法有时比较棘手并涉及很多位操作。但是,看到以下代码的结果我感到有点震惊:
Stopwatch Test = new Stopwatch();
int a = 0;
int i = 0, j = 0, l = 0;
double c = 0, d = 0;
for (i = 0; i < 32; i++)
{
Test.Start();
for (j = Int32.MaxValue, l = 1; j != 0; j = -j + ((j < 0) ? -1 : 1), l = -l)
{
a = l * j;
}
Test.Stop();
Console.WriteLine("Product: {0}", Test.Elapsed.TotalMilliseconds);
c += Test.Elapsed.TotalMilliseconds;
Test.Reset();
Test.Start();
for (j = Int32.MaxValue, l = 1; j != 0; j = -j + ((j < 0) ? -1 : 1), l = -l)
{
a = (j < 0) ? -j : j;
}
Test.Stop();
Console.WriteLine("Comparison: {0}", Test.Elapsed.TotalMilliseconds);
d += Test.Elapsed.TotalMilliseconds;
Test.Reset();
}
Console.WriteLine("Product: {0}", c / 32);
Console.WriteLine("Comparison: {0}", d / 32);
Console.ReadKey();
}
结果:
产品: 8558.6
比较: 9799.7
快速解释:j
是辅助替代变量,类似于(...), 11, -10, 9, -8, 7, (...)
,直到达到零,l
是存储j
的变量}的符号,a
是测试变量,我希望它始终等于j
的模数。测试的目的是检查使用乘法或条件运算符将a
设置为此值是否更快。
有人可以对这些结果发表评论吗?
非常感谢。
答案 0 :(得分:5)
你的第二次测试不仅仅是比较,而是if语句。
这可能是在JUMP/BRANCH
中的CPU
指令中转换的,涉及branch prediction(可能有管道的块)然后可能比简单的乘法慢(即使没有那么多) )。
答案 1 :(得分:3)
对优化编译器进行此类断言通常非常困难。他们做了许多技巧,使简单的案例与实际代码不同。也就是说,你不仅仅是在进行比较,而是在一个非常紧密的循环中进行比较/分配。你正在处理的线程可能不得不在分支处暂停多次;乘法可以分配任意次数,只要最后一次分配仍然是最后一次,那么可以同时进行多次乘法。
按照一般规则,使代码清晰,忽略小的时间问题,除非它们成为问题。 如果确实存在速度问题,那么良好的跟踪/计时工具将比在特定情况下知道一个操作是否比其他操作更快更好地指导您。
答案 2 :(得分:0)
我想我会做的一个评论是你在第二次操作中做了很多事情:
a = (j < 0) ? -j : j;
你不仅要进行比较,而且还有效地将“if..else ..”与?进行比较。运算符和j的否定。
答案 3 :(得分:0)
您应该尝试运行此测试1000次左右并使用avrage来比较您现在从未在背景中进行的CLR