我可以选择进行指针比较或 strcmp。我知道字符串永远不会超过 8 个字符,并且我的目标是 64 位平台。他们会表现同样出色,还是其中一个会是更好的选择?我可以想象这在平台和编译器之间可能会有所不同,如果是这样,我想知道有关平台/编译器细节的详细信息。
克,
科恩
指针比较几乎肯定会更快,因为它是两个指针的单个比较(可能将一个或两个加载到寄存器中),而 strcmp,即使内联且第一个字节不同(最佳情况)也需要取消引用两个指针。如果 strcmp 未内联,则有一个函数调用并返回,如果第一个字节没有不同(并且不是两个 NUL),则有多个取消引用。
为了更深入地了解这一点,我建议使用这两种方法查看程序的汇编器输出。
注意:我假设您的声明“我可以选择进行指针比较或 strcmp”是正确的,只有在您的字符串都已知具有唯一内容的情况下才会出现这种情况。
第一个问题应该是:这个比较是我的可执行文件中的关键路径吗?如果不是,则性能问题可能无关紧要,因为影响可能很小以至于无关紧要。
比较指针只是 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)
等等......),您可以比较foo.sixtyfourbits == foo2.sixtyfourbits
......但我发现这样代码味道极差。如果你真的想用这种方式编码,请添加大量解释性注释。我相信以这种方式编码会使您的代码不可读和不可维护,而性能收益可能非常小。