【发布时间】:2014-10-26 15:26:04
【问题描述】:
我需要找到向量中的最大元素,所以我使用std::max_element,但我发现它是一个非常慢的函数,所以我编写了自己的版本并设法获得 x3 更好的性能,这里是代码:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/time.h>
double getRealTime()
{
struct timeval tv;
gettimeofday(&tv, 0);
return (double) tv.tv_sec + 1.0e-6 * (double) tv.tv_usec;
}
inline int my_max_element(const std::vector<int> &vec, int size)
{
auto it = vec.begin();
int max = *it++;
for (; it != vec.end(); it++)
{
if (*it > max)
{
max = *it;
}
}
return max;
}
int main()
{
const int size = 1 << 20;
std::vector<int> vec;
for (int i = 0; i < size; i++)
{
if (i == 59)
{
vec.push_back(1000000012);
}
else
{
vec.push_back(i);
}
}
double startTime = getRealTime();
int maxIter = *std::max_element(vec.begin(), vec.end());
double stopTime = getRealTime();
double totalIteratorTime = stopTime - startTime;
startTime = getRealTime();
int maxArray = my_max_element(vec, size);
stopTime = getRealTime();
double totalArrayTime = stopTime - startTime;
std::cout << "MaxIter = " << maxIter << std::endl;
std::cout << "MaxArray = " << maxArray << std::endl;
std::cout << "Total CPU time iterator = " << totalIteratorTime << std::endl;
std::cout << "Total CPU time array = " << totalArrayTime << std::endl;
std::cout << "iter/array ratio: = " << totalIteratorTime / totalArrayTime << std::endl;
return 0;
}
输出:
MaxIter = 1000000012
MaxArray = 1000000012
Total CPU time iterator = 0.000989199
Total CPU time array = 0.000293016
iter/array ratio: = 3.37592
平均而言,std::max_element 比 my_max_element 多花 3 倍的时间。
那么为什么我能够如此轻松地创建一个更快的 std 函数呢?既然 std 太慢了,我应该停止使用 std 并编写自己的函数吗?
注意:起初我认为这是因为我在 for 循环中使用整数 i 而不是迭代器,但现在这似乎无关紧要了。
编译信息:
g++ (GCC) 4.8.2
g++ -O3 -Wall -c -fmessage-length=0 -std=c++0x
【问题讨论】:
-
你在编译优化吗?
-
您是否尝试过颠倒通话顺序?缓存可能在这里起作用。
-
this 是我得到的。 max_element 太慢了,甚至 max_element 也快了 70%
-
my_max_element在空向量上中断,而std::max_element需要检测和处理这种情况 -
您的计时代码实现了灾难性取消,这使得整个问题变得毫无意义。请正确处理时间值(并且,在它们有意义的范围内进行,而不是在调度程序的变化范围内)。也就是说,从不 做任何事情,例如减去两个几乎相同的 float/double 值,并且永远不要使用 double 作为时间。此外,执行至少运行 2-3 秒(最好是 10 或 20 秒)而不是几微秒的基准测试。单个中断等很容易导致您看到的内容。
标签: c++ gcc vector iterator max