c++ 比较两个稍大的对象是否相等

j9per5c4  于 2023-11-19  发布在  其他
关注(0)|答案(3)|浏览(109)

我必须比较两个较大的物体是否相等。
对象的属性:
1.通过值包含所有成员(因此没有指针跟随)。
1.它们还包含一些stl::array
1.它们包含了1和2成立的其他一些对象。
1.大小可达几KB。
1.一些members将更有可能与其他不同,因此如果首先比较,则会导致比较操作的更快中断。
1.对象不会改变。基本上,算法只是计算有多少对象是相同的。每个对象只与几个“主”对象比较一次。
比较这些对象的最佳方法是什么?我看到三个选项:
1.只需使用普通的、非重载的operator==即可。
1.重载==并执行逐个成员的比较,从可能不同的成员开始。
1.重载==并将对象视为普通字节字段,然后逐字比较。

一些想法:

选项1看起来不错,因为它意味着最少的工作量(以及引入错误的机会)。
选项2看起来不错,因为我可以利用启发式方法来判断哪些元素最有可能不同,但它可能仍然较慢,因为选项1的内置==快得离谱。
选项3似乎是最“低级”的优化,但编译器可能也会对选项1进行优化。
因此,问题是:

  • 有没有一个众所周知的最佳方法来解决这个问题?
  • 其中一个选择是绝对不行的吗?
  • 我需要考虑别的吗?
rbpvctlc

rbpvctlc1#

Default ==对于小对象来说是快速的,但是如果你有大数据成员要比较,试着找到一些优化,考虑存储的特定数据和它们的更新方式,重新定义一个比默认值更“聪明”的重载==比较运算符。
正如许多人已经说过的,选项3是错误的,因为字段通常被填充以尊重数据对齐,并且出于优化原因,添加的字节没有初始化为0(可能这在DEBUG版本中完成)。
我可以建议您探索将检查分为两个阶段的选项:

  • 第一阶段,创建某种小而快的成员来“压缩”示例的状态(就像哈希一样);每当一些大的字段发生变化时,这个字段就会更新,例如stl-array的元素。然后首先检查频繁变化的字段和这个“压缩”状态,以进行保守的比较(例如,数组中所有int的总和,或者可能是xor)
  • 第二阶段,对每个成员进行深入测试。这是最慢但完整的检查,但可能仅在某些时候激活
mepcadol

mepcadol2#

问得好
如果你有一些关于哪些成员可能不同的启发式方法,那就使用它,这样重载operator ==并首先检查可疑的成员似乎是个好主意。
关于字节比较(也称为memcmp和friends)-可能会因为结构成员对齐而出现问题。也就是说,编译器有时会在结构布局中放置“空格”,以便每个成员都有所需的对齐。这些空格未初始化,通常包含垃圾。
这可以通过对整个对象进行显式零初始化来解决。但是,我看不出memcmp与自动operator ==相比有什么优势,这是一个成员级的比较。它可能会保存一些代码量(对memcpy的单个调用与显式读取和比较相比),但是从性能Angular 来看,这似乎是差不多的。

kfgdxczn

kfgdxczn3#

如果对象不是微不足道的,请记住memcmpfollowing note

  • 此函数读取对象表示,而不是对象值,并且通常仅对**没有填充的可复制对象有意义。*

->所以,我会重载对象的==,并直接进行成员比较。我也不建议使用哈希比较,因为calculating hashs of e.g. large strings is a costly operation

相关问题