我必须比较两个较大的物体是否相等。
对象的属性:
1.通过值包含所有成员(因此没有指针跟随)。
1.它们还包含一些stl::array
。
1.它们包含了1和2成立的其他一些对象。
1.大小可达几KB。
1.一些members
将更有可能与其他不同,因此如果首先比较,则会导致比较操作的更快中断。
1.对象不会改变。基本上,算法只是计算有多少对象是相同的。每个对象只与几个“主”对象比较一次。
比较这些对象的最佳方法是什么?我看到三个选项:
1.只需使用普通的、非重载的operator==
即可。
1.重载==
并执行逐个成员的比较,从可能不同的成员开始。
1.重载==
并将对象视为普通字节字段,然后逐字比较。
一些想法:
选项1看起来不错,因为它意味着最少的工作量(以及引入错误的机会)。
选项2看起来不错,因为我可以利用启发式方法来判断哪些元素最有可能不同,但它可能仍然较慢,因为选项1的内置==
快得离谱。
选项3似乎是最“低级”的优化,但编译器可能也会对选项1进行优化。
因此,问题是:
- 有没有一个众所周知的最佳方法来解决这个问题?
- 其中一个选择是绝对不行的吗?
- 我需要考虑别的吗?
3条答案
按热度按时间rbpvctlc1#
Default ==对于小对象来说是快速的,但是如果你有大数据成员要比较,试着找到一些优化,考虑存储的特定数据和它们的更新方式,重新定义一个比默认值更“聪明”的重载==比较运算符。
正如许多人已经说过的,选项3是错误的,因为字段通常被填充以尊重数据对齐,并且出于优化原因,添加的字节没有初始化为0(可能这在DEBUG版本中完成)。
我可以建议您探索将检查分为两个阶段的选项:
mepcadol2#
问得好
如果你有一些关于哪些成员可能不同的启发式方法,那就使用它,这样重载
operator ==
并首先检查可疑的成员似乎是个好主意。关于字节比较(也称为
memcmp
和friends)-可能会因为结构成员对齐而出现问题。也就是说,编译器有时会在结构布局中放置“空格”,以便每个成员都有所需的对齐。这些空格未初始化,通常包含垃圾。这可以通过对整个对象进行显式零初始化来解决。但是,我看不出
memcmp
与自动operator ==
相比有什么优势,这是一个成员级的比较。它可能会保存一些代码量(对memcpy
的单个调用与显式读取和比较相比),但是从性能Angular 来看,这似乎是差不多的。kfgdxczn3#
如果对象不是微不足道的,请记住
memcmp
的following note:->所以,我会重载对象的==,并直接进行成员比较。我也不建议使用哈希比较,因为calculating hashs of e.g. large strings is a costly operation。