c++具有 max_element & 的函数迭代器 = 慢 3 倍
当我调用以下函数时,我正在开发的程序变慢了三倍。 如果不被调用几百万次也不错。
double obterNormLarguraBanda(const std::vector<double>& v, int periodos)
{
int aa;
double maximo, minimo, valor;
std::vector<double>::const_iterator inicio;
if (v.size() < periodos)
{
inicio = v.begin();
}
else
{
inicio = v.end() - periodos;
}
maximo = *max_element(inicio, v.end(), excludeWrong);
minimo = *min_element(inicio, v.end(), excludeWrong);
return (v.back()-minimo)/(maximo - minimo);
}
bool excludeWrong(double i, double j)
{
if (i==-1 || j==-1) return false;
return i<j;
}
periodos
的值为 500。 还有其他方法可以显着加快此功能吗?
The program I am developing gets three times slower when I call the following function.
It wouldn't be bad if it was not called a couple million of times.
double obterNormLarguraBanda(const std::vector<double>& v, int periodos)
{
int aa;
double maximo, minimo, valor;
std::vector<double>::const_iterator inicio;
if (v.size() < periodos)
{
inicio = v.begin();
}
else
{
inicio = v.end() - periodos;
}
maximo = *max_element(inicio, v.end(), excludeWrong);
minimo = *min_element(inicio, v.end(), excludeWrong);
return (v.back()-minimo)/(maximo - minimo);
}
bool excludeWrong(double i, double j)
{
if (i==-1 || j==-1) return false;
return i<j;
}
periodos
takes the value 500.
Is there another way to speed up significantly this function?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当整个步骤可以在一个函数中完成时,
max_element
和min_element
都在范围内迭代。我相信某些编译器在其 STL 中有一个
minmax_element
函数,但我不相信它在标准中。你可以自己写。我最初将其编写为非模板版本,但如果您有一个好的编译器,那么它应该没有什么区别。尝试这样的事情(未经测试)
max_element
andmin_element
are both iterating through the range, when the entire step could be done in one function.I believe some compilers have a
minmax_element
function in their STL, but I do not believe it is in the standard. You could write your own. I originally wrote this as an untemplated version, but if you have a good compiler it should make no difference.Try something like this (untested)
与其他人所说的相反,我不相信用单个
minmax_element 替换对
会显着提高性能,因为使用 1 个操作迭代 2*n 次或使用 2 个操作迭代 n 次几乎没有区别。std::max_element()
和std::min_element()
的两个调用()然而,重要的是从算法中完全消除这两个调用。也就是说,找到最小和最大元素,然后在新数据进入时检查这些元素,而不是再次将新数据与整个容器进行比较。
Contrary to what others say, I don't believe replacing the two calls to
std::max_element()
andstd::min_element()
with a singleminmax_element()
would improve performance in a significant manner, because iterating 2*n times with 1 operation or iterating n times with 2 operations makes little to no difference.What would make a difference however is to eliminate the two calls altogether from your algorithm. That is, find the minimum and maximum elements and then check against those when new data comes in, rather than comparing new data against the entire container again.
您可以用一个
std::minmax_element()
替换这两个调用。You could replace those two calls with a single
std::minmax_element()
.“慢 3 倍”相对于什么 - 另一个实现,或者只是不调用这个函数?在第二种情况下,可能只是算法复杂性导致速度变慢。
您没有解释您的代码是如何准确使用的,在某些情况下,您可以缓存最小/最大的计算,而不是在循环中执行此操作。例如,如果输入向量很少改变,那么每次都重新计算是没有意义的。即使它发生变化,您也可以更新最小值/最大值,而无需遍历 periodos 元素(动态编程可能会有所帮助)。
您还可以检查生成的程序集以检查奇怪的函数调用(例如迭代器安全检查),我知道至少 MSVC 2005/2008 即使在发布模式下也默认启用它们(请参阅 _SCL_SECURE 宏)。
"3 times slower" with respect to what - to another implementation, or to just not calling this function? In the second case it is possible that it is just algorithmic complexity that makes it slower.
You didn't explain how your code is used exactly, in some cases you could cache the calculation of the min/max instead of doing that in a loop. For example, if the input vector is rarely changed, it doesn't make sense to recalculate that every time. And even when it changes, you can update min/max without going over
periodos
elements (dynamic programming might help).You could also check the generated assembly to check for strange function calls (eg iterators secure checks), I know that at least MSVC 2005/2008 has them enabled by default even in Release mode (see the _SCL_SECURE macro).
这不是有关性能的具体问题的答案,因此也许它没有价值。但似乎
excludeWrong
比较函数会导致意外或可能与实现相关的结果。如果比较的第一个值是-1
,那么它可以被计算为所有情况的最小值和最大值。我使用 gcc v4.0.2 和 Microsoft 编译器 v15.00.21022.08 进行了测试。例如,以下内容:prints:
也许这就是期望的结果,但看起来有点奇怪。
This isn't an answer to the specific question about performance, so maybe it has no value. But it seems that the
excludeWrong
compare function would cause unexpected or possibly implementation-dependent results. If the first value compared is-1
, then it may be computed as both the min and the max for all cases. I tested with both gcc v4.0.2 and Microsoft's compiler v15.00.21022.08. For example, the following:prints:
Maybe that is the desired result, but it seems a bit odd.