Are compilers smart enough to detect a no-op function?
If I write a function like this:
void doMaybeNothing()
{
#ifndef IM_开发者_JS百科LAZY
doSomething();
#endif
}
Are modern compilers smart enough to detect a no-op function and optimize so that there are no cycles wasted? Or is there always a small performance impact?
Assuming the body of the function is available at compile-time or link-time (i.e., it's not in a dynamically linked library), most modern compilers should get rid of calls to functions that do nothing (if optimizations are enabled, of course).
Effectively, this is just a form of inline expansion, which allows the body of a function to be expanded anywhere it is called, so long as the results are the same. If the function does nothing, then it will simply expand to nothing wherever it is inlined.
Simple functions like this will be inlined and removed.
For gcc, with an input like
#include <stdio.h>
void no_op () {}
int main () {
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
no_op();
return 0;
}
The result (with -O1
) is
.section __TEXT,__text,regular
.section __TEXT,__textcoal_nt,coalesced
.section __TEXT,__const_coal,coalesced
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16
.text
.align 2
.globl _no_op
_no_op:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
@ lr needed for prologue
bx lr
.align 2
.globl _main
_main:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
@ lr needed for prologue
mov r0, #0
bx lr
.subsections_via_symbols
Note that no call to no_op
in main
is generated.
If the call to doMaybeNothing is in the same source file, then most modern compilers will optimize it completely away.
If the call is in a separate source file, and especially if it's in a different library, then you will often end up with the small overhead of the function call - but the function will immediately return.
One more thing: this sounds like premature optimization. Don't worry about things like this until you've profiled your program.
Besides what the other answers have already mentioned, one other thing to consider is that the #ifndef
is handled by the pre-processor, which just does text-replacement - not the compiler.
The compiler never sees anything except what the pre-processor spits out. So, depending on whether IM_LAZY
is defined or not, the compiler will only see one of the following:
void MaybeDoNothing()
{
}
or
void MaybeDoNothing()
{
doSomething();
}
精彩评论