【发布时间】:2013-07-06 06:52:10
【问题描述】:
我可以选择进行指针比较或 strcmp。 我知道字符串永远不会超过 8 个字符,并且我的目标是 64 位平台。 他们会表现同样出色,还是其中一个会是更好的选择?我可以想象这在平台和编译器之间可能会有所不同,如果是这样,我想知道有关平台/编译器细节的详细信息。
gr,
科恩
【问题讨论】:
我可以选择进行指针比较或 strcmp。 我知道字符串永远不会超过 8 个字符,并且我的目标是 64 位平台。 他们会表现同样出色,还是其中一个会是更好的选择?我可以想象这在平台和编译器之间可能会有所不同,如果是这样,我想知道有关平台/编译器细节的详细信息。
gr,
科恩
【问题讨论】:
指针比较几乎肯定会更快,因为它是两个指针的单个比较(可能将一个或两个加载到寄存器中),而 strcmp,即使内联和第一个字节不同(最佳情况)也需要取消引用两者指针。如果 strcmp 没有内联,则有一个函数调用并返回,如果第一个字节没有不同(并且都不是 NUL),则有多个取消引用。
为了更深入地了解这一点,我建议使用这两种方法查看程序的汇编器输出。
注意:我假设您的声明“我可以选择进行指针比较或 strcmp”是正确的,只有在您的字符串都已知具有唯一内容的情况下才会出现这种情况。
【讨论】:
strcmp() 完成,无需特殊的硬件支持(在 little-endian 机器上)。
第一个问题应该是:这个比较是我的可执行文件中的关键路径吗?如果不是,则性能问题可能无关紧要,因为影响可能很小以至于无关紧要。
比较指针只是strcmp的一个子集,因为如果碰巧在不同的内存位置,你不知道字符串值是否相同。您可能必须在设计中考虑到这一点。
指针比较肯定更快。但是,如果您有 8 个字节的保证字符串长度,您可以在没有 strcmp 的情况下比较字符串,并使用具有 8 个字节长度并且可以直接比较的数据类型。这样,您基本上具有与指针比较相似的速度,并且还比较字符串。但是当然,这只有在确保所有字符串都是 8 个字节的情况下才是可靠的,如果它们更短,则用零填充剩余部分。
【讨论】:
两个字符串(即使是 8 个字符的短字符串)可以相等但地址不同,因此比较指针与使用 strcmp 不同。
但您的应用程序可能会使用 hash-consing 或 string-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。我相信以这种方式编码会使您的代码不可读和不可维护,而性能收益可能非常小。
【讨论】: