使用kcachegrind并在调试模式下运行代码,我发现我的程序的瓶颈是两个向量进行比较的点。
if (v1 == v2) {
// DO
}
如何提高效率?这样更好吗
if (v1[0] == v2[0]) {
if (v1 == v2) {
// DO
}
}
第一行将过滤一些无用的比较。
在此之前我尝试了
if (!v2.empty())
if (v1 == v2)
// DO
但是我发现它们几乎总是不空的。因此,还包括空()的额外时间。
我不得不说矢量的大小很小。 2~4个元素。在极少数情况下,它们将延伸到10。
更新 感谢Mats Petersson,似乎通过在优化模式下进行编译,可以进一步提高性能。
答案 0 :(得分:5)
如果它真的是你的程序的瓶颈,你应该重构你的设计。比较两个范围始终在 O(N)中运行。
如果您真的想保留您的设计,那么您可以选择:保持这些表演或做出猜测。您可能希望查找 更改最多的向量部分。当然如果你有完全随机的push_backs,那就不值得了。然后你可以开始测试这些元素。
答案 1 :(得分:4)
我会尝试一下,但我希望v1 == v2
的内部变成类似的东西:
for(int i = 0; i < v1.size && i < v2.size; i++)
{
if (v1[i] != v2[i])
return false;
}
[以上可能不是它实际实现的方式,但显示为“它的工作原理”]
所以,如果索引0是最常见的不同元素,那么你只会勉强获得一些东西。
无论如何,尝试一下(这可能比在这里要求更快!)
当然,鉴于评论,这个特定问题的主要部分是“不要在关闭优化时对代码进行基准测试/配置文件”。当在微小的细节和紧密的循环代码中进行测量时,很容易使性能提高10倍,然后关闭优化[并且如果“调试模式”也能够进行额外的检查,并且这样做以确保没有超出范围的使用,等,我们可以看到100-1000x较慢的代码]
答案 2 :(得分:2)
第二个代码块只是略微提高效率,但它是不正确的:考虑如果一个或两个向量为空会发生什么。这里唯一的节省来自避免调用开销和循环设置开销,当字符串在第一个字符中不同时。这些节省不值得使您的计划复杂化,因为它们太小了。
如果您希望节省更多资金,请考虑使用以不同方式实现相等性的自定义类替换字符串:例如,您可以预先计算并存储向量的哈希码,并使用逐个元素的比较只有当哈希码不同时才会使用。
答案 3 :(得分:2)
由于您的类型是基本整数类型,您可以尝试 *使用memcmp
memcpy
获取两个缓冲区(void*
)并返回0 iff buffers具有相等的内存块
bool equal = v1.size() == v2.size() && memcmp(&v1.front(), &v2.front(), sizeof(v1[0]) * v1.size()) == 0;
(*) - 我突出显示单词试图表明它没有必要会有所帮助,但这是可能性之一
答案 4 :(得分:0)
我想你所拥有的任何实现都将从验证数组大小是否相等开始,然后继续逐个遍历元素并进行比较(尽可能快地返回false - 在第一个区别)。所以你的建议没有多大帮助,std :: mismatch也没有。
但是,如果你可以保持你的矢量排序,也许更聪明的检查是可行的。你能吗?