TL; DR:这样做的明显的方式,并确保你的编译器优化它。
如果没有一个完整的,可重现的程序例子,很难对性能进行推理。所以让我们从一个简单的实现开始:
#include <array>
#include <algorithm>
std::array<int, 362856427> a = {};
int main()
{
a[500] = 1;
a[5000] = 1;
a[50000] = 1;
a[500000] = 1;
auto counter = 0u;
for (auto i = 0u; i < a.size(); ++i) {
if (a[i] != 1)
++counter;
}
return counter != 362856423;
}
时间这个,我得到了1.79秒的用户时间。然后我意识到自己的错误,并将-O3
添加到我的编译命令中。这是更好的:
g++ -std=c++17 -g -Wall -Wextra -O3 16385733.cpp -o 16385733
time ./16385733
0.07user 0.08system 0:00.16elapsed 98%CPU (0avgtext+0avgdata 2212maxresident)k
我们可以尝试简化环路,但是这没有可测量的差异(优化已经击败了我们这一个):
for (auto i = 0u; i < a.size(); ++i)
counter += a[i] != 1;
另一种方法是使代码更清晰,通过使用标准算法:
auto counter = a.size() - std::count(a.begin(), a.end(), 1);
这一直比明显循环长50%。
如果输入阵列大得多,你也许可以通过并行这样的计算获得:
auto counter = 0ul;
#pragma omp parallel for reduction(+:counter)
for (auto i = 0ul; i < a.size(); ++i)
counter += a[i] != 1;
我的基准测试表明这为作为标准算法慢,当数组大小为362856427 ,并没有更快,当它上升到3628564270.
有几种方法来重新写在等价形式:
for (auto i: a)
counter += i != 1;
for (auto p = a.data(); p < end; ++p)
counter += *p != 1;
所有这些都表现出类似的性能,而OpenMP并没有得到改进。
那么简单的答案是
- 做的明显的方式
- 请确保您的编译器优化和
- 基准的替代品。
um ...'if(t [i]!= 1)'。在这里使用'memcmp'是很奇怪的。 – Dave 2013-05-05 14:53:09
什么让你觉得“那个解决方案”('t [i] == 1)不是最快的一个? – dialer 2013-05-05 14:53:54
这个“不是那个解决方案”是关于t [i] == 1的。我不会,如果它是最快的我需要最快的请不要在这里聊天。 – Yoda 2013-05-05 14:54:29