【问题标题】:performance of pointer comparison vs string comparison strcmp指针比较与字符串比较 strcmp 的性能
【发布时间】:2013-07-06 06:52:10
【问题描述】:

我可以选择进行指针比较或 strcmp。 我知道字符串永远不会超过 8 个字符,并且我的目标是 64 位平台。 他们会表现同样出色,还是其中一个会是更好的选择?我可以想象这在平台和编译器之间可能会有所不同,如果是这样,我想知道有关平台/编译器细节的详细信息。

gr,

科恩

【问题讨论】:

    标签: c pointers strcmp


    【解决方案1】:

    指针比较几乎肯定会更快,因为它是两个指针的单个比较(可能将一个或两个加载到寄存器中),而 strcmp,即使内联和第一个字节不同(最佳情况)也需要取消引用两者指针。如果 strcmp 没有内联,则有一个函数调用并返回,如果第一个字节没有不同(并且都不是 NUL),则有多个取消引用。

    为了更深入地了解这一点,我建议使用这两种方法查看程序的汇编器输出。

    注意:我假设您的声明“我可以选择进行指针比较或 strcmp”是正确的,只有在您的字符串都已知具有唯一内容的情况下才会出现这种情况。

    【讨论】:

    • 我认为 strcmp 比较多个字符(如果 64 位则为 8 个)
    • @perreal memcmp 可能,strcmp 不可能(除非硬件有专门为其设计的特殊指令)。
    • 也可以strcmp() 完成,无需特殊的硬件支持(在 little-endian 机器上)。
    【解决方案2】:

    第一个问题应该是:这个比较是我的可执行文件中的关键路径吗?如果不是,则性能问题可能无关紧要,因为影响可能很小以至于无关紧要。

    比较指针只是strcmp的一个子集,因为如果碰巧在不同的内存位置,你不知道字符串值是否相同。您可能必须在设计中考虑到这一点。

    指针比较肯定更快。但是,如果您有 8 个字节的保证字符串长度,您可以在没有 strcmp 的情况下比较字符串,并使用具有 8 个字节长度并且可以直接比较的数据类型。这样,您基本上具有与指针比较相似的速度,并且还比较字符串。但是当然,这只有在确保所有字符串都是 8 个字节的情况下才是可靠的,如果它们更短,则用零填充剩余部分。

    【讨论】:

    • OP 说“永远不会超过 8 个字符”,而不是“正好 8 个字符”。比较字符串意味着两次内存读取......绝对不如比较指针快。
    • 是的,这就是为什么我提到字符串应该确保为 8 字节长度。如果这确实很关键,那应该不是问题。如果不是,这仍然由程序员决定,但可能值得一提。
    【解决方案3】:

    两个字符串(即使是 8 个字符的短字符串)可以相等但地址不同,因此比较指针与使用 strcmp 不同。

    但您的应用程序可能会使用 hash-consingstring-interning,即具有规范字符串(例如,像 Glib quarks

    除非您对其进行衡量,否则您不应该过多关注性能。请注意,一些编译器(具有足够高的优化级别)能够很好地优化strcmp 调用。

    附录

    如果您的字符串不是真正的任意字符串而是 8 个字节,您可以使用联合声明它们(编译器将适当地对齐并可能优化)。

    typedef union { 
        char eightbytes[8];
        int64_t sixtyfourbits;
    } mytype_t;
    

    然后你可能会初始化

    mytype_t foo = {.eightbytes="Foo"};
    

    如果您确定字符串是 0 字节填充的(就像上面的初始化一样;但是如果您堆分配它们,则需要在填充之前将它们归零,例如使用 strncpy(p->eightbytes, somestring, 8) 等...),您可以比较 @ 987654329@... 但我觉得这样的代码味道极差。如果你真的想这样编码,添加很多解释性的 cmets。我相信以这种方式编码会使您的代码不可读和不可维护,而性能收益可能非常小。

    【讨论】:

      最近更新 更多