我正在写一个代码,其中优化是一个真正的问题,我确实需要使这段代码尽可能快地运行。
所以我有这样的事情:
a是 double 数,x是整数。
在我的特定情况下,x始终为2或3
double c1[3] = {5345.4364654, 43346.6876978, 1224324.654756};
double c2[3] = {49876.642543678, 1104.57576756};
...
..
if (x>2)
a = c1[0]*x*x*x-c1[1]*x*x+c1[2]*x;
else
a = c2[0]*x*x+c2[1]*x;
我想知道如果删除if..else并执行类似的操作是否会更快
double c [2][3] = {
{5345.4364654, 43346.6876978 , 1224324.654756},
{0 ,49876.642543678, 1104.575767561}
};
a = c1[x-2][0]*x*x*x-c1[x-2][1]*x*x+c1[x-2][2]*x;
在我看来,如果将零乘以编译器视为“特殊情况”,第二个代码将运行得更快,但是我不确定
如果你们有什么想法请帮助:)
非常感谢
最佳答案
如今乘法运算的速度非常快,因此避免分支可能比跳过一个乘法乘以0更重要。
我将分解方程式如下:
double c [2][3] = {
{5345.4364654, 43346.6876978 , 1224324.654756},
{0 ,49876.642543678, 1104.575767561}
};
a = ((c1[x-2][0]*x-c1[x-2][1])*x+c1[x-2][2])*x;
请注意,如果
c
数组确实是一个编译时间常数(并且如果您通过使其为const来帮助编译器),则可以提示编译器预先计算x = 2和x = 3的值,如下所示:switch (x)
{
case 2:
a = ((c1[x-2][0]*x-c1[x-2][1])*x+c1[x-2][2])*x;
break;
case 3:
a = ((c1[x-2][0]*x-c1[x-2][1])*x+c1[x-2][2])*x;
break;
default:
// this should never happen
}
这可能表明编译器只是直接编译答案。
这很有可能也会起作用:
switch (x)
{
case 2:
case 3:
a = ((c1[x-2][0]*x-c1[x-2][1])*x+c1[x-2][2])*x;
break;
default:
// this should never happen
}
但是,如果
c
确实是一个编译时间常数,而x
确实是2或3,那么您只有两个输入和两个结果,因此您最好在计算器上算出两个答案,并在switch语句中对它们进行硬编码,如果我真的很担心速度。