比较两个向量,使它更有效

comparing two vectors, make it more efficient

本文关键字:有效 向量 两个 比较      更新时间:2023-10-16

使用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也没有。

然而,如果你能保持你的向量排序,也许一个更聪明的检查是可行的。你能吗?