比较两个有些大的对象是否相等

时间:2015-04-28 10:45:23

标签: c++

我必须比较两个较大的对象是否相等。

对象的属性:

  1. 按值包含所有成员(因此没有指示符。)
  2. 它们还包含一些stl::array
  3. 它们包含一些其他对象,其中1和2持有。
  4. 大小可达几KB。
  5. members中的某些operator==更可能与其他==不同,因此如果首先进行比较,会导致比较操作更快中断。
  6. 对象不会改变。基本上,算法只是计算有多少对象是相同的。每个对象只与一些“主”对象进行一次比较。
  7. 比较这些对象的最佳方法是什么?我看到三个选项:

    1. 只需使用普通的,非重载的==
    2. 重载==并执行逐个成员比较,从可能不同的成员开始。
    3. 重载for(int iClient = 0; iClient < Server.numClients; iClient++) { Client client = Server.GetClient(iClient) String string = Server.GetString(iClient) Client.SendMessage(string); } 并将对象视为普通字节字段并逐字比较。
    4. 一些想法:
      选项1似乎很好,因为它意味着工作量最少(以及引入错误的机会) 选项2似乎很好,因为我可以利用关于哪些元素最不可能的启发式。但也许它仍然较慢,因为选项1的内置SendToAll速度非常快 选项3似乎是最“低级”优化的,但这也是编译器可能也对选项1做的。

      所以问题是:

      • 有没有一种众所周知的最佳解决方法?
      • 其中一个选项绝对禁止吗?
      • 我还需要考虑别的吗?

2 个答案:

答案 0 :(得分:4)

对于小对象,默认==是快速的,但是如果要比较大数据成员,请尝试查找一些优化,考虑存储的特定数据及其更新方式,重新定义重载==比较运算符更多&# 34;更聪明&#34;而不是默认的。

正如许多人已经说过的,选项3是错误的,因为字段通常被填充以尊重数据对齐,并且出于优化原因,添加的字节未初始化为0(可能这在DEBUG版本中完成) )。

我可以建议您探索将支票分为两个阶段的选项:

  • 第一阶段,创造某种小型和小型的快速成员&#34;压缩&#34;实例的状态(像哈希一样思考);每次某些大字段更改时,此字段都可以更新,例如stl-array的元素。比检查经常更改的字段,这&#34;压缩&#34;状态首先进行保守的比较(例如,数组中所有int的总和,或者可能是xor)
  • 第二阶段,对每个成员使用深入测试。这是最慢但完整的检查,但有时可能会被激活

答案 1 :(得分:2)

一个好问题。

如果你有一些关于哪些成员可能不同的启发式 - 请使用它。因此,重载operator ==并首先检查可疑成员似乎是一个好主意。

关于逐字节比较(又名memcmp和朋友) - 由于结构成员对齐可能会有问题。即编译器有时会放置空格&#34;在您的结构布局中,以便每个成员都需要对齐。那些没有初始化,通常包含垃圾。

这可以通过对整个对象进行显式零初始化来解决。但是,我没有看到memcmp与自动operator ==的任何优势,这是一个成员明智的比较。它可能可以节省一些代码大小(单次调用memcpy vs显式读取和比较),但从性能角度来看,这似乎差不多。