C++:使用更大的比较器意外提升性能
C++: Unexpected performance boost using greater comparator
我正在将算法问题的解决方案提交给在线评分系统,起初,解决方案超过了时间限制,大约需要~4s。
我完全确定复杂性是正确的,所以我开始优化我的部分代码,没有什么了不起的事情发生,直到我注意到一些非常奇怪的事情。
我正在使用对的优先级队列,我选择实现我自己的比较器
struct Comparator{
bool operator()(pair<int, int> node1, pair<int, int> node2){
return node1.second < node2.second;
}
};
当我将其更改为<algorithm>
库的greater
比较器时,性能得到了显着提升;解决方案通过了,只需要~300ms。
额外信息:我正在使用优先级队列来实现Dijkstra的"调整"版本。队列声明是:priority_queue<pair<int, int>, vector<pair<int, int>>, Comparator> q;
,我将其更改为:priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
.
我真的很好奇为什么会发生这种情况。对我来说,比较器应该做什么非常简单,我想不出更有效的方法。
任何帮助将不胜感激:)
有几种情况可能导致性能差异:
struct Comparator{
bool operator()(pair<int, int> node1, pair<int, int> node2){
return node1.second < node2.second;
}
};
与。std::greater
- 自定义比较器按值获取对象,
std::greater
按引用获取对象。我怀疑这会产生超过 10% 的效果。 std::greater
比较node2.first < node1.first
如果node2.first != node1.first
否则它是node2.second < node1.second
.这种比较与Comparator
完全不同,后者比较node1.second < node2.second
。由于比较结果不同,因此代码将经历完全不同的路径。经历不同的路径会对大O的复杂性和性能产生深远的影响。这很可能是造成差异的真正原因。
有关std::greater
参考,请查看std::pair::operator<
正在做什么:
如果
lhs.first<rhs.first
,则返回true
。否则,如果rhs.first<lhs.first
,则返回false
。否则,如果lhs.second<rhs.second
,则返回true
。否则,返回false
。
- std::设置自定义比较器
- C++中"std::sort"比较器的不同类型
- 将 std::set 与基于键的比较器一起使用
- 带自定义比较器的最小优先级队列
- 函数类作为比较器
- 优先级队列自定义比较器
- 什么是自定义比较器以及如何在 C++ 的排序函数中使用它?
- 没有默认构造函数作为模板参数的自定义比较器
- set_intersection使用自定义设置比较器
- 如何为集合 c++ 建立比较器
- C++复杂情况的比较器通过参数问题
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- 对没有比较器或λ函数的向量进行排序?
- "operator()"在重载运算符方法中是什么意思,在priority_queue(STL)中用作C++中的比较器?
- 用户定义的结构是否有默认C++比较器?
- C++设置了一个用于排序的比较器和另一个用于唯一性的比较器
- 使用迭代器的自定义比较器函数
- C++对λ比较器EXC_BAD_ACCESS进行排序
- 如果要求比较器是严格的总排序,而不仅仅是严格的弱排序,C++标准算法会更快吗?
- C++:使用更大的比较器意外提升性能