C语言 strcmp 空字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6203102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:49:51  来源:igfitidea点击:

strcmp for empty string

cstrcmp

提问by Pablitorun

I was reviewing some code and I saw someone do a

我正在一些代码,我看到有人做了一个

if (0 == strcmp(foo,""))

I am curious because I think it would be faster to do a

我很好奇,因为我认为做一个会更快

if (foo[0] == '
if( !*str )
')

Is this correct or is strcmp optimized enough to make them the same.

这是正确的还是 strcmp 优化到足以使它们相同。

(I realize that even if there was some difference it would be small, but am thinking you save at least a few instructions by using my method.)

(我意识到即使有一些差异也会很小,但我认为您使用我的方法至少保存了一些指令。)

采纳答案by Gui13

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.

您是对的:由于调用strcmp()会将堆栈管理和内存跳转加到实际的 strcmp 指令中,因此您只需检查字符串的第一个字节即可获得一些指令。

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

出于好奇,您可以在此处查看 strcmp() 代码: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 #ifdefand obscure __GNUSOMETHING, but it's actually rather simple!)

(我以为代码会充满#ifdef和晦涩难懂__GNUSOMETHING,但实际上相当简单!)

回答by ralphtheninja

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() 是一个函数调用,因此有一个函数调用开销。foo[0] 是直接访问数组,所以显然更快。

回答by x4u

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:

我认为在这种情况下使用 strcmp 没有任何好处。编译器我足够聪明,可以优化它,但它不会比直接检查 '\0' 字节快。实现者可能选择了这个结构,因为他认为它更具可读性,但我认为在这种情况下这是一个品味问题。虽然我会写检查有点不同,因为这是似乎最常用于检查空字符串的习语:

if( *str )

and

bool isEmpty(char * str) {
   return 0==std::strcmp(str,"");
}
bool isEmpty2(char * str) {
   return str[0]==0;
}

to check for a non empty string.

检查非空字符串。

回答by Hyman V.

+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)!

+1 到 Gui13 以提供 gcc stdlib strcmp 源的链接(http://sourceware.org/git/?p=glibc.git;a=blob;f=string/strcmp.c;h=bd53c05c6e21130b091bd75c3fc93872dd71fe4b;h = 头)!

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):

你是对的,strcmp 永远不会比直接比较更快 [1],但问题是,编译器会优化它吗?我很害怕尝试测量它,但我惊喜地发现它是多么容易。我的示例代码是(省略标题):

            .file   "emptystrcmptest.cc"
            .section .rdata,"dr"
    LC0:
            .ascii "
        .file   "emptystrcmptest.cc"
emptystrcmptest.cc:10:2: warning: no newline at end of file
        .text
        .align 2
        .p2align 4,,15
.globl __Z7isEmptyPc
        .def    __Z7isEmptyPc;  .scl    2;      .type   32;     .endef
__Z7isEmptyPc:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        popl    %ebp
        cmpb    
int isEmpty(const char *string)
{
    return ! *string;
}

int isNotEmpty(const char *string)
{
    return *string;
}

int isNullOrEmpty(const char *string)
{
    return string == NULL || ! *string;
}

int isNotNullOrEmpty(const char *string)
{
    return string != NULL && *string;
}
, (%eax) sete %al movzbl %al, %eax ret .align 2 .p2align 4,,15 .globl __Z8isEmpty2Pc .def __Z8isEmpty2Pc; .scl 2; .type 32; .endef __Z8isEmpty2Pc: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax popl %ebp cmpb ##代码##, (%eax) sete %al movzbl %al, %eax ret
" .text .align 2 .globl __Z7isEmptyPc .def __Z7isEmptyPc; .scl 2; .type 32; .endef __Z7isEmptyPc: pushl %ebp movl %esp, %ebp subl , %esp movl $LC0, 4(%esp) movl 8(%ebp), %eax movl %eax, (%esp) call _strcmp movl %eax, -4(%ebp) cmpl ##代码##, -4(%ebp) sete %al movzbl %al, %eax movl %eax, -4(%ebp) movl -4(%ebp), %eax leave ret .align 2 .globl __Z8isEmpty2Pc .def __Z8isEmpty2Pc; .scl 2; .type 32; .endef __Z8isEmpty2Pc: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax cmpb ##代码##, (%eax) sete %al movzbl %al, %eax popl %ebp ret emptystrcmptest.cc:10:2: warning: no newline at end of file .def _strcmp; .scl 2; .type 32; .endef

And I tried compiling that, first with gcc -S -o- emptystrcmptest.ccand then with gcc -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.

我尝试编译它,首先使用gcc -S -o- emptystrcmptest.cc然后使用gcc -S -O2 -o- emptystrcmptest.cc. 令我惊喜的是,虽然我不能很好地阅读程序集,但未优化的版本清楚地显示出差异,而优化的版本则清楚地表明两个函数产生了相同的程序集。

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).

如果您正常编码,请使用更具可读性的版本(恕我直言,可能是 strcmp 或 strlen 或 [0]==0 取决于上下文)。

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.

如果您正在编写高效的代码,您希望每秒被调用数千或数百万次,(a) 测试实际上效率更高的代码,以及 (b) 如果可读版本实际上太慢,请尝试编写一些可以编译为更好的组装。

With gcc -S -o- emptystrcmptest.cc:

gcc -S -o- emptystrcmptest.cc

##代码##

With gcc -S -O2 -o- emptystrcmptest.cc:

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.

[1] 尽管要小心——在比直接测试零更复杂的情况下,库和编译器代码通常会比手工编写的代码更好。

回答by τεκ

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.

一个好的优化编译器可能会优化掉函数调用,然后从内联函数中消除循环。您的方法不可能更慢,尽管它有可能保持相同的速度。

回答by pickypg

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, strcmpneeds 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., isEmptywould probably just flip isNotEmpty)

并让编译器为您优化。无论如何,strcmp需要最终检查,'\0'以便您始终至少等于它。(老实说,我可能会让编译器优化上面的内部共享,例如,isEmpty可能只是翻转isNotEmpty

回答by mdaguerre

Access to an array is order 1 in execution time, so, it′s faster than the function.

访问数组的执行时间是 1 阶,因此,它比函数更快。

回答by Brandon Moretz

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.

这是尽可能微优化,但我想如果您在索引 foo 之前添加空检查(除非您知道它永远不会为空),它会在技术上节省函数调用的开销。