【发布时间】:2021-02-11 23:31:51
【问题描述】:
我正在尝试编写一个 fast 方法来计算 double 类型的一维数组的累积和,但是我的幼稚实现非常慢,我不确定如何加快速度完善我的方法。
我的第一种方法是创建一个相同维度的空数组,并在 for 循环中使用相应的累积和填充它。
void cumsum_d(int size, double arr[size]) {
double* out = (double*)malloc(size*sizeof(double));
for (int i = 0; i < size; ++i) {
double temp = 0;
for (int j = 0; j < i+1; ++j) {
temp += arr[j];
}
out[i] = temp;
}
for (int i = 0; i < size; ++i) {
arr[i] = out[i];
}
free(out);}
我的第二次尝试是使用递归修改数组
void cumsum_d2(int size, double arr[size], int ind) {
if (ind == 0) {
return;
}
double temp = 0;
for (int i = 0; i < ind+1; ++i) {
temp += arr[i];
}
arr[ind] = temp;
cumsum_d2(size, arr, ind-1);}
对于长度为 1000 的数组,它的运行时间约为。 1ms 而例如NumPy 实现NumPy.cumsum() 只需要大约 60μs。
对于如何加快我的代码速度,是否有任何提示/技巧,或者是否存在任何重大缺陷?
【问题讨论】:
-
您不需要一遍又一遍地计算较小的累积总和。您已经计算过一次,只需添加当前值即可。 ...
accum[0] = values[0]; accum[1] = accum[0] + values[1]; accum[2] = accum[1] + values[2]; ... -
想想Schlemiel the Painter。别忘了带上水桶。
-
当然很慢,因为你正在使用
O(n^2)而不是O(n)。您的out[i+1]应计算为out[i] + arr[i+1]。 -
for (int i = 1; i < size; ++i) arr[i] += arr[i - 1];将是我的第一次尝试。 -
我一定忘记了我的存储桶@FredLarson 非常恰当地指出...感谢大家的帮助,并对这个(事后看来)微不足道的问题感到抱歉!