char数组的快速比较?

时间:2010-05-28 14:37:00

标签: c++

我目前正在代码库中工作,其中IPv4地址表示为u_int8的指针。等于运算符的实现如下:

bool Ipv4Address::operator==(const u_int8 * inAddress) const
{
    return (*(u_int32*) this->myBytes == *(u_int32*) inAddress);
}

这可能是禁食的解决方案,但它会导致GCC编译器警告:

ipv4address.cpp:65: warning: dereferencing type-punned pointer will break strict-aliasing rules

如何在不破坏严格别名规则且不丢失性能点的情况下正确重写比较?

我考虑使用memcmp或此宏:

#define IS_EQUAL(a, b) \
    (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])

我认为宏是最快的解决方案。

你推荐什么?

更新
我刚刚阅读了文章Squeezing performance out of memcmp usage,它解释了编译器(Visual Studio,但也许还有GCC)如何优化!memcmp(..)调用。

2 个答案:

答案 0 :(得分:10)

我会选择memcmp()

  1. 更便携
  2. 我通常尽量不要比我的编译器/语言更聪明。您正在尝试比较内存内容和(取决于编译器选项)memcmp()的实现应该是最有效的方法。
  3. 另外想想如果你的编译器没有内联memcmp(),你将遇到函数上下文切换

    你确定你需要努力优化吗?您是否已经检查过您的程序大部分时间都在进行此类操作?

答案 1 :(得分:3)

您从GCC收到错误的原因是长度超过1个字节的任何内容都喜欢与对象大小的倍数对齐。 32位整数喜欢从32位边界开始。 char变量(有符号,无符号或普通)可以位于任何字节边界上,例如3对于处理器的32位读取不起作用。

在您的情况下,对于4个字节(32位),调用memcmp的开销可能比实际比较字节的代码要多。

试试这个:

bool Ipv4Address::operator==(const u_int8 * inAddress) const
{
    return myBytes[0] == inAddress[0]
        && myBytes[1] == inAddress[1]
        && myBytes[2] == inAddress[2]
        && myBytes[3] == inAddress[3];
}

看妈妈,不使用this->成员函数代码!

至于效率,这段代码可能在调用memcpy并从中执行返回的同时执行(不执行memcpy的内容)。这假设memcpy没有内联。知道如何为通用和大型案例编写编译器库,我怀疑这个代码仍然比memcpy的内联版本更小更快。虽然证据是打印两个版本的装配清单并进行比较。

修改
注意:将实现声明为内联或将代码放在类声明中,将比定义危险的宏更好。它将更安全并包含相同数量的代码。我喜欢内联方法版本,因为它更易读,更易于维护。