如何在C++; < > C++中有没有一种更快的方法来完成下面的三重组合,而不是按元素执行规则的顺序组合元素?p> const short n = 1000; float a[n];⋅ for(int i = 0; i<n; i++)⋅ a[i] = (float)i; int b = 0; for(int i = 0; i<n; i++) for(int j = 0; j<n; j++) for(int m = 0; m<n; m++) b += a[i]*a[j]*a[m]; cout<<"b: "<<b<<endl; const short n=1000; 浮动a[n];⋅ 对于(int i=0;i
,从数学上讲,乘积之和可以简化为数组的和,立方 因此,您可以使用此选项:如何在C++; < > C++中有没有一种更快的方法来完成下面的三重组合,而不是按元素执行规则的顺序组合元素?p> const short n = 1000; float a[n];⋅ for(int i = 0; i<n; i++)⋅ a[i] = (float)i; int b = 0; for(int i = 0; i<n; i++) for(int j = 0; j<n; j++) for(int m = 0; m<n; m++) b += a[i]*a[j]*a[m]; cout<<"b: "<<b<<endl; const short n=1000; 浮动a[n];⋅ 对于(int i=0;i,c++,optimization,C++,Optimization,,从数学上讲,乘积之和可以简化为数组的和,立方 因此,您可以使用此选项: // assuming a is an std::vector or similar b = std::accumulate(a.begin(), a.end(), 0); b = b*b*b; 通过使用以下代码,您可以说服自己: #include <iostream> #include <array> #include <numeric> int main() { auto
// assuming a is an std::vector or similar
b = std::accumulate(a.begin(), a.end(), 0);
b = b*b*b;
通过使用以下代码,您可以说服自己:
#include <iostream>
#include <array>
#include <numeric>
int main()
{
auto a = std::array{2, 3, 5, 7};
auto sum = 0;
for (auto i : a) {
for (auto j : a) {
for (auto k : a) {
sum += i*j*k;
}
}
}
std::cout << sum << "\n";
sum = std::accumulate(a.begin(), a.end(), 0);
std::cout << sum*sum*sum << "\n";
}
这简化为:
sum{i in a}( i*sum{j in a}( j*sum{k in a}(k) ) )
sum{i in a}( i*sum{j in a}(j)*sum{k in a}(k) )
sum{i in a}(i)*sum{j in a}(j)*sum{k in a}(k)
sum{i in a}(i) ^3
建议1:在启用优化的情况下构建代码。您似乎经常在
i
和j
不变的地方计算a[i]*a[j]
。优化器可能会注意到,也可能不会注意到。当最终结果是int
时,为什么要用整数填充float
数组?只需替换a即可[i] ,a[j]
,a[m]
使用i
、j
、m
时,您应该会得到相同的结果。启用优化后,代码将花费大约3秒的时间。如果您观察到更大的内容,则表示您测量错误或没有给出正确的结果。此外,您通过溢出b
调用未定义的行为。非常优雅!是否正确这是否转化为向量运算(如注释中指定的OP)?@BenJones OP说“我们需要计算三元组的点积”。我不知道他的意思,因为点积只取两个向量。如果他指的是元素相乘,那么是的,同样的简化也适用(但结果是一个向量,而不是一个标量)。如果他指的是标量三积,那么我认为它不起作用,但我懒得去证实。
sum{i in a}( i*sum{j in a}( j*sum{k in a}(k) ) )
sum{i in a}( i*sum{j in a}(j)*sum{k in a}(k) )
sum{i in a}(i)*sum{j in a}(j)*sum{k in a}(k)
sum{i in a}(i) ^3