Is there any performance difference between the following two cases?
is there any performance difference between the following two cases:
First:int test_some_condition(void);
if( some_variable == 2 && test_some_condition())
{
//body
}
Second:
int test_so开发者_如何学Pythonme_condition(void);
if( some_variable == 2 )
{
if(test_some_condition())
{
//body
}
}
UPDATE: I know how to create a test and measure the performance of each case or to look at the assembly produced for each case but I am sure I am not the first one to come across this question and it would be great if someone who has already tested that can be me a simple yes/no answer.
Difference in terms of what?
Readability? Yes, there's a difference. The first is much clearer and much better expresses your intent. And it also takes up fewer lines in the editor, which is not necessarily an advantage in itself, but it does make the code easier to read and grok at a glance for anyone who comes behind and wants to edit it.
Performance/"speed"? No. I'd be willing to bet actual money that there is absolutely no discernible difference once you run those two snippets of code through a compiler with optimizations turned on. And it wouldn't take much to convince me to bet on that same case even with optimizations disabled.
Why? Because in C (and all of the C-derived languages that I know of), the &&
operator performs short-circuit evaluation, which means that if the first condition evaluates to false, then it doesn't even bother to evaluate the second condition, because there's no way that the entire statement could ever turn out to be true.
Nesting the if
statements was a common "optimization" trick in the bad old days of VB 6 when the And
operator did not perform short-circuit evaluation. There's no purpose that I can imagine to using it in C code, unless it enhances readability. And honestly, if you run across a compiler that doesn't render these two code snippets completely equivalent in terms of performance, then it's time to throw that compiler away and stop using it. This is the most basic optimization under the sun, a "low-hanging fruit" for compiler writers. If they can't get this right, I wouldn't trust them with the rest of your code.
But, in general, worrying about this sort of thing (which definitely falls under the category of a "micro-optimization") is not helping you to write better code or become a better programmer. It's just causing you to waste a lot of time asking questions on Stack Overflow and contributing to the reputation of users like me who post this same answer to 2–3 similar questions a week. And that's time you're not spending writing code and improving your skills in tangible ways.
The only way anyone can really tell with a modern compiler is to look at the machine code.
There should be no difference. If there is a difference, it's likely not measurable (even if you do it millions of times you won't get conclusive results).
Testing these two examples in a loop running 10.000.000 times gives:
$ time ./test1
real 0m0.045s
user 0m0.044s
sys 0m0.001s
$ time ./test2
real 0m0.045s
user 0m0.043s
sys 0m0.003s
Also, keep in mind that if the first part of the expression fails, the second expression will never be evaluated. This is maybe not so clear in the first example.
Also, in conditions where the first evaluated expression returns false:
$ time ./test1_1
real 0m0.035s
user 0m0.034s
sys 0m0.001s
$ time ./test2_1
real 0m0.035s
user 0m0.034s
sys 0m0.000s
If you are thinking whether the first version always calls test_some_condition
but the second version calls it only if the first condition is true, then the answer is that both versions are equivalent because the AND operator is lazy and will not evaluate its second argument if the first is already false.
The standard guarantees this behaviour. This makes it legal to say:
if (array_size > n && my_array[n] == 1) { ... }
This would be broken code without the laziness guarantee.
The two samples are logically equivalent, provided that compound conditions are lazily evaluated, meaning that in a && b
, b
won't be evaluated when a
is known to be false. So even if there were a difference I wouldn't care because that might be an artefact (or a bug) of the compiler you're using, and it might change with the next release or bugfix.
精彩评论