strcmp 表示空字符串
我正在审查一些代码,我看到有人做了 a
if (0 == strcmp(foo,""))
我很好奇,因为我认为这样做会更快
if (foo[0] == '\0')
这是正确的还是 strcmp 优化得足以使它们相同。
(我意识到即使有一些差异也会很小,但我认为您使用我的方法至少可以节省一些说明。)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
你是对的:由于调用
strcmp()
添加了堆栈管理和内存跳转到实际的 strcmp 指令,因此只需检查字符串的第一个字节即可获得一些指令。出于好奇,您可以在此处检查 strcmp() 代码: http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb=HEAD
(我认为代码将填充
#ifdef
并且晦涩难懂__GNUSOMETHING
,但实际上相当简单!)You're right: since calling
strcmp()
adds up the stack management and the memory jump to the actual strcmp instructions, you'll gain a few instructions by just checking the first byte of your string.For your curiosity, you can check the strcmp() code here: http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb=HEAD
(I thought the code would be filled with
#ifdef
and obscure__GNUSOMETHING
, but it's actually rather simple!)strcmp() 是一个函数调用,因此具有函数调用开销。 foo[0] 是直接访问数组,所以显然更快。
strcmp() is a function call and thus has a function call overhead. foo[0] is direct access to the array, so it's obviously faster.
我认为在这种情况下使用 strcmp 没有任何优势。编译器可能足够聪明,可以优化它,但它不会比直接检查“\0”字节快。这个的实现者可能选择了这个结构,因为他认为它更具可读性,但我认为在这种情况下这是一个品味问题。尽管我写的检查有点不同,因为这似乎是最常用于检查空字符串
和
检查非空字符串的习惯用法。
I see no advantage of using strcmp in this case. The compiler my be clever enough to optimize it away but it won't be any faster than checking for the '\0' byte directly. The implementer of this might have chosen this construct because he thought it is more readable but I think this is a matter of taste in this case. Although I would write the check a little different as this is the idiom that seems to be used most often to check for an empty string:
and
to check for a non empty string.
+1 Gui13提供了gcc stdlib strcmp源的链接(http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb =头)!
你是对的,strcmp 永远不会比直接比较更快[1],但问题是,编译器会优化它吗?我很害怕尝试测量它,但我惊喜地发现它是如此简单。我的示例代码是(省略标头):
我尝试编译该代码,首先使用 gcc -S -o-emptystrcmptest.cc,然后使用 gcc -S -O2 -o-emptystrcmptest.cc 。令我惊喜的是,虽然我不能很好地阅读程序集,但未优化的版本清楚地显示出差异,而优化的版本清楚地显示两个函数生成了相同的程序集。
所以,我想说,一般来说,担心这种程度的优化是没有意义的。
如果您正在使用嵌入式系统的编译器,并且知道它不能处理这种简单的优化(或者根本没有标准库),请使用手动编码的特殊情况版本。
如果您正常编码,请使用更具可读性的版本(恕我直言,根据上下文可能是 strcmp 或 strlen 或 [0]==0 )。
如果您正在编写高效的代码,您预计每秒会被调用数千或数百万次,(a)测试实际上更有效,(b)如果可读版本实际上太慢,请尝试编写一些可以编译为更好的组装。
使用
gcc -S -o-emptystrcmptest.cc
:使用
gcc -S -O2 -o-emptystrcmptest.cc
:[1] 尽管要小心——以防万一比直接针对零进行测试复杂,库和编译器代码通常会比手工编写的代码更好。
+1 to Gui13 for providing a link to the source of gcc stdlib strcmp (http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;hb=HEAD)!
You are correct that strcmp can never be faster than a direct comparison[1], but the question is, will the compiler optimise it? I was intimidated to try measuring that, but I was pleasantly surprised at how easy it was. My sample code is (omitting headers):
And I tried compiling that, first with
gcc -S -o- emptystrcmptest.cc
and then withgcc -S -O2 -o- emptystrcmptest.cc
. To my pleasant surprise, although I can't read the assembly very well, the non-optimised version clearly showed a difference, and the optimised version clearly showed the two functions produced identical assembly.So, I would say that in general, there's no point worrying about this level of optimisation.
If you are using a compiler for an embedded system and know it not to handle this sort of simple optimisation (or don't have a standard library at all), use the hand-coded special-case version.
If you are coding normally, use the more readable version (imho that may be strcmp or strlen or [0]==0 depending on context).
If you are writing highly efficient code you expect to be called thousands or millions of times a second, (a) test which is actually more efficient and (b) if the readable version is actually too slow, try to write somethign which will compile to better assembly.
With
gcc -S -o- emptystrcmptest.cc
:With
gcc -S -O2 -o- emptystrcmptest.cc
:[1] Although be careful -- in cases any more complicated than a direct test against zero, the library and compiler code a typically WILL be better than hand-crafted code.
一个好的优化编译器可能会优化函数调用,然后消除内联函数中的循环。尽管有可能速度相同,但您的方法不可能更慢。
A good optimizing compiler might optimize away the function call and then eliminate the loop from the inlined function. There's no way that your method could be slower, though there is a chance that it will be the same speed.
对数组的访问在执行时间上是顺序 1,因此,它比函数更快。
Access to an array is order 1 in execution time, so, it´s faster than the function.
这是微观优化,但我想如果您在索引 foo 之前添加了空检查(除非您知道它永远不会为空),那么从技术上讲,它会节省函数调用的开销。
This is as micro-optimizing as it gets, but I suppose if you added a null check before you index foo (unless you know it'll never be null) it would technically save the overhead of a function call.
显然,它会更快,并且如果您打算继续使用它,则可能值得将您自己的代码放入内联函数,甚至可能是宏中:
并让编译器为您优化它。无论如何,
strcmp
需要最终检查'\0'
,以便您始终至少等于它。 (老实说,我可能会让编译器优化上述内容的内部共享,例如,isEmpty
可能只是翻转isNotEmpty
)It's clearly going to be faster, and it's probably worth placing your own code in an inline function, or maybe even a macro, if you plan on moving forward with it:
and let the compiler optimize that for you. Regardless,
strcmp
needs to eventually check for'\0'
so you're always at least equal to it. (honestly, I'd probably let the compiler optimize internal sharing of the above, e.g.,isEmpty
would probably just flipisNotEmpty
)