c++ - C++:使用更大的比较器实现意外的性能提升
问题描述
我正在将算法问题的解决方案提交给在线评分系统,起初,解决方案超过了时间限制,大约需要 4 秒。
我完全确定复杂性是正确的,所以我开始优化我的部分代码,但没有发生什么大事,直到我注意到一些非常奇怪的事情。
我正在使用对优先级队列,我选择实现自己的比较器
struct Comparator{
bool operator()(pair<int, int> node1, pair<int, int> node2){
return node1.second < node2.second;
}
};
当我将其更改为库的greater
比较器时<algorithm>
,性能有了显着提升;解决方案通过了,只用了大约 300 毫秒。
额外信息:我正在使用优先级队列来实现 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
。
推荐阅读
- php - 在存档页面的帖子中查看所有 ACF 灵活内容
- mysql - 如何通过多对多关系从 SQL 提取中排除具有相关关键字的行
- mysql - 无法使用 spark-submit 连接 hive mysql Metastore
- r - 无法将日期因子转换为日期时间
- java - 在地图中将行转置或转换为列
- google-cloud-platform - GCP:列出每个资源的可授予角色
- prometheus - 追踪:如何使用分配来无限增加价值
- c# - 无法信任 ASP.NET Core 中的本地 HTTPS 证书
- javascript - 从另一个 Google 电子表格动态更新公式
- c - 动态结构内存之间的指针