@Jamie Wong: if the string is 1Meg long, then you have to check 1 million bytes before you find the terminating null; This is a pretty big lose when you are only interested in the case where the string has either zero, or more than zero characters.
–
SingleNegationEliminationJun 1 '11 at 14:52

Your way will invariably be faster. Even if you ignore the fact that strcmp has call overhead, it must eventually do that same memory access too. Hence it can only be equal or slower speed.
–
Mike KwanJun 1 '11 at 14:53

2

@Mike: I think the spirit of the question is more to do with cases where strcmp might do something wiser than the direct array access; what with buffer overruns and the like. I think the answer is that in this case, there aren't any.
–
SingleNegationEliminationJun 1 '11 at 14:55

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:

yeah I like that better, where I work though us some strict guidelines about being explicit in the conditional....so even if it doesn't make a whole lot of sense I have to explicitly check for '\0' or 0
–
PablitorunJun 1 '11 at 15:58

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

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.

+1 @Jack This lends great credence to @Brandon Moretz's comment. Good post. I'm still not sure which I prefer in terms of pure readability, but this definitely makes a good point in terms of premature-optimizations.
–
pickypgJun 3 '11 at 15:48

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.

I think you missed the point. OP is not checking for a null pointer but for a zero-length string. There's never a purpose to performing both the direct check and the strcmp call since the effects are the same.
–
R..Jun 1 '11 at 22:05

1

@R I believe you should re-read my response. I was simply stating that he should perform a null check on a pointer before blindly indexing it. I didn't say anything about calling strcmp.
–
Brandon MoretzJun 1 '11 at 22:17

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 flip isNotEmpty)

I'm pretty sure that determining f() == !a() is way beyond the abilities of any optimizer.
–
mikerobiJun 1 '11 at 15:21

@mike Correct, but it can still optimize the call to be inline rather than pushing the same pointer onto the stack. This also prevents potentially "non-standard" code littering the codebase.
–
pickypgJun 1 '11 at 17:13