我正在写一个代码,其中优化是一个真正的问题,我确实需要使这段代码尽可能快地运行。

所以我有这样的事情:

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语句中对它们进行硬编码,如果我真的很担心速度。

07-25 20:13