chinakow
chinakow

Reputation: 43

Does a function that only calls another function slow things down?

I saw some code that was something like this

int *func2(int *var) {
    //Do some actual work
    return var;
}

int *func1(int *var) {
    return func2(var);
}

int main() {
    int var;
    var = func1(&var);
    return 0;
}

This seems like an incredible waste to me but I figured the intermediate function might have previously had two function that it could call or there are some plans for expansion in the future. I was just wondering if compilers like gcc can detect this sort of thing and eliminate the useless function in the actual program or if this sort of thing actually wastes CPU cycles at runtime?

Upvotes: 4

Views: 1487

Answers (4)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

The super quick answer: Yes, maybe.

The quick answer: Yes, but usually not enough that you should care, and sometimes not at all.

The full answer: If the functions are all in the same translation unit and the compiler doesn't suck, the extra layer of function call will just get optimized out, and there will be zero impact on performance. Otherwise, if you're making external function calls, expect a small but nonzero performance cost. Most of the time it doesn't matter, but on functions that are super-short where every cycle counts, it could make your program twice as slow, or worse. Some worst-case examples:

  1. A function like getc that just pulls the next byte from a buffer, advances the position, and returns (in the common case where the buffer is non-empty).
  2. A function that advances a state machine via a trivial operation and returns, for example processing a single byte of a UTF-8 character.
  3. Locking/synchronization primitives. This is a bit of a special case because the actual atomic memory access should dominate the execution time, making overhead seem insignificant. But if your intended usage case is just to hold locks for a single trivial operation (e.g. lock(); a++; unlock();) then even a small amount of added time with the lock held could have drastic effects on contention performance if the lock is highly contended.

Finally, the what-you-should-do answer: Write your code in the most natural way possible until testing/measurement shows you there's a performance problem. Only then should you think about uglifying your code for the sake of performance.

Upvotes: 1

Mysticial
Mysticial

Reputation: 471199

In most cases, if you turn up the compiler optimizations high enough, such trivial functions will be inlined. Thus there is no overhead.

So the answer to your question is: Yes, the compiler is usually smart enough to eliminate the call.
So don't worry about it unless you need to.

You can also use the inline keyword to make it more explicit: (although the compiler is still free to ignore it)

inline int *func1(int *var) {
    return func2(var);
}

Upvotes: 4

Matthew Whited
Matthew Whited

Reputation: 22433

It would depend on the compiler and runtime environment. If the method call is on a stack there will be slight extra overhead from incrementing the stack. But in this case everything is by pointer so this might as well be a tail call and will probably be inlined. Inlining/tail call will cause the function to operate similar to a jump instead of a stack being incremented; meaning it would be similar to a loop or a goto when running.

Upvotes: 0

Matthew Flaschen
Matthew Flaschen

Reputation: 284786

Don't do premature optimization. Focus on writing readable code. Even without optimization, the extra function call probably has a minimal effect on performance. The compiler may choose to inline it.

If you have performance issues later, you can test and profile to find the bottlenecks.

Upvotes: 12

Related Questions