比较两个向量,使它更有效
comparing two vectors, make it more efficient
使用kcachegrind并在调试模式下运行代码,我发现我的程序的瓶颈是比较两个向量的点。
if (v1 == v2) {
// DO
}
我怎样才能使它更有效率?这样更好吗
if (v1[0] == v2[0]) {
if (v1 == v2) {
// DO
}
}
第一行将过滤一些无用的比较。
在那之前我试过
if (!v2.empty())
if (v1 == v2)
// DO
然而,我发现它们几乎总是不空的。因此,empty()的额外时间也包括在内。
我不得不说向量的大小大多很小。2 ~ 4元素。在极少数情况下,它们将扩展到10。
更新:感谢Mats Petersson,通过在优化模式下编译,似乎有更多的性能改进。
如果它确实是程序的瓶颈,您应该重构您的设计。比较两个范围总是在O(N)中运行。
如果你真的想保留你的设计,那么,你要么有两个选择:保留那些性能,要么进行猜测。您可能想要查找将更改最多的向量部分。当然,如果你有完全随机的推回,这是不值得的。然后你就可以开始测试这些元素了。
我会给它一个尝试,但我希望v1 == v2
的内部变成类似的东西:
for(int i = 0; i < v1.size && i < v2.size; i++)
{
if (v1[i] != v2[i])
return false;
}
[上面可能不是它实际实现的方式,而是显示为"它是这样工作的"]
所以,只有当索引0是最常见的不同元素时,你才会获得一些东西。
无论如何,请尝试一下(无论如何,这可能比在这里询问更快!)
当然,这个问题的主要部分,根据评论,是"不要在关闭优化的情况下对你的代码进行基准测试/配置"。当测量微小的细节和紧环的代码位时,很容易得到10倍差的性能,然后优化被关闭[如果"调试模式"还启用额外的检查和这样的事情来确保没有越界使用,等等,我们可以看到100-1000倍慢的代码]
第二个代码块只是稍微有效一点,但它是不正确的:考虑如果一个或两个向量为空会发生什么。这里唯一的节省是避免了当字符串的第一个字符不同时调用开销和循环设置开销。这些节省并不值得使您的程序复杂化,因为它们太小了。
如果你想节省更多的资源,考虑用实现相等性的自定义类替换字符串:例如,你可以预先计算和存储向量的哈希码,并且只在哈希码不同时才使用逐个元素的比较。
由于您的类型是基本的整数类型,您可以尝试*使用memcmp
memcpy
获得两个缓冲区(void*
)并返回0,如果缓冲区具有相等的内存块
bool equal = v1.size() == v2.size() && memcmp(&v1.front(), &v2.front(), sizeof(v1[0]) * v1.size()) == 0;
我想您的任何实现都将从验证数组大小相等开始,然后继续逐个遍历元素并比较它们(在第一个差异上尽快返回false)。所以你的建议没有多大帮助,std::mismatch也没有。
然而,如果你能保持你的向量排序,也许一个更聪明的检查是可行的。你能吗?
- 在C++中初始化向量映射的最有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- C++有效地找到向量中第一个最接近的匹配值?
- 如何有效地操作满足给定谓词的向量中的所有项目?
- 检查两个向量是否并行的最有效方法
- 当表示为对象的一维向量时,有效地旋转 NxM 矩阵 (C++)
- 如何有效地实现将向量的数据分配给多个变量?
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 如何在C++中有效地将数组移动到向量
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 如何有效地用第二个值对向量对进行分组
- 从长(且合理)稀疏向量中选择随机元素的最有效方法是什么?
- 如何在 CUDA 中(有效地)将大量向量相互比较
- 基于整数向量执行位排列的有效方法?
- 如何使用C++有效地合并排序与向量
- C++:检查向量中的元素是否大于另一个具有相同索引的元素的有效方法?
- 如何有效地规范化向量C++
- 为什么优先级队列是使用堆实现的,而我们可以更有效地使用向量来实现它
- 字符串向量的有效组合
- C++中的有效向量运算符/对临时对象的引用