C ++ - 如何提高这种方法的执行速度

时间:2013-03-07 15:57:12

标签: c++ arrays

我正在努力提高我的即将发布的作业的编程技能,它涉及解决问题,同时使其尽可能高效地运行。我知道这是一个相当克制/小块的代码,但如果有什么能使它运行得更快。

该方法采用一个包含事务详细信息的数组,有100个用于维护循环的事务数。所以我得到平均数量的股票,然后返回它。不能流利的英语,所以希望它有意义,谢谢

double Analyser::averageVolume()
{
    // Your code
    double averageNumShares = 0;
    for(int i = 0; i < nTransactions; i++)
    {
        averageNumShares += tArray[i].numShares;
    }
    averageNumShares = averageNumShares / nTransactions;
    return averageNumShares;
    //return 0
}

6 个答案:

答案 0 :(得分:4)

如果您需要计算n个数字的平均值,我担心您无法在示例代码中超过线性时间approch加速...

除非将其用作另一个更复杂的算法的一部分,在这个算法中你可能无需计算平均值或沿着这些线的某些东西,所以取平均值将是一个O(n)运算基本上涉及将数组的所有元素和一个除以元素的数量相加。这正是你所拥有的。

答案 1 :(得分:1)

为什么没有对象的另外两个值 - 运行总计和项目数?

然后计算平均值就可以利用这些数字。快速简单(可以是内联函数!)。

答案 2 :(得分:1)

这是一种额外的方法,类似于Ed Heal建议的方法,应该对舍入误差不太敏感。平均值的舍入误差随着累积和的大小而增加。这对您来说可能是也可能不是问题,但需要注意这一点。

这是一个迭代算法,可以最小化平均值中的舍入误差,这是我在Ross的旧版本(大约1998年)中首次遇到的:

double Analyser::averageVolume()
{
  double averageNumShares = 0.0;

  for (int i = 0; i < nTransactions; i++)
  {
    double delta = (tArray[i].numShares - averageNumShares) / (i+1);
    averageNumShares += delta;
  }

  return averageNumShares;
}

这通过导出平均值的递归定义来实现。也就是说,给定样本x[1],...,x[j],...,x[N],您可以计算样本{{1}中的第一个M+1样本的平均值和第一个x[M+1]样本的平均值:

M

要了解两种方法的舍入误差,请尝试计算10 ^ 7个样本的平均值,每个样本等于1035.41。您的原始方法返回(在我的硬件上),平均值为1035.40999988683。上面的迭代方法返回1035.41的精确平均值。

不幸的是,两者在某些时候都是O(N)。您的原始方案有N个添加和一个分区。迭代方案有N个加法,减法和除法,因此您需要为准确性付出更多。

答案 3 :(得分:0)

如果使用gcc更改优化级别。

答案 4 :(得分:0)

简短回答: 这段代码与速度一样好。您可以调整的是如何编译它。或者显然,如果这是一个选项,请在汇编中重写它。

“拉伸”答案: 现在......如果你真的想尝试获得更好的性能,已经尝试过使用所有可用的编译器优化标志和优化,并且你已经准备好以更快的速度来破坏代码可读性,那么可以考虑重写:

for(int i = 0; i < nTransactions; i++)
    {
        averageNumShares += tArray[i].numShares;
    }

作为

pointerValue = &(tArray[0].numShares);
pointerIncrement = sizeof(tArray[0]);
for(int i = 0; i < nTransactions; i++)
    {
        averageNumShares += *(pointerValue++pointerIncrement);
    }

通过显示编译器,您可以在每次循环迭代时跳过固定的偏移量,从而获得更好的性能。一个好的编译器应该能够看到你的初始代码。新代码可能会让您的性能更差。这实际上取决于编译器的具体情况,并且我不建议使用这种方法,除非您迫切希望获得比编译器提供的更好的性能,并且不希望跳转到使用内联汇编或内部函数(如果任何可用的。)

答案 5 :(得分:0)

int i= nTransactions;
while(i--){// test for 0 is faster
    averageNumShares += (q++)->numShares;// increment pointer is faster than offset
}