0

In JavaScript, there are, often, huge performance penalties for writing functions. For example, if you use this function:

function double(x){ return x*2; }

inside an inner loop, you are probably hitting your performance considerably, so it is really profitable to inline that kind of function for intensive applications. Does this, in general, hold for C? Am I free to create those kind of functions for everything, and rest assured the compiler will do the job, or is hand inlining still important?

MaiaVictor
  • 51,090
  • 44
  • 144
  • 286
  • 2
    You're comparing a compiled to an interpreted language. In general it doesn't since C is compiled. Hand inlining isn't much important anymore. Just let compiler do the job. – Jack Jun 22 '14 at 02:50
  • Useful link: http://stackoverflow.com/questions/1759300/when-should-i-write-the-keyword-inline-for-a-function-method – Ilya Jun 22 '14 at 02:51
  • 1
    The problem with that kind of answer/topic is that it always includes a `notice the compiler has the freedom not to inline the function` observation, so you end up still not knowing if in practice you should or shouldn't hand-inline your functions. – MaiaVictor Jun 22 '14 at 02:52
  • For example, I was just wondering if I should create a function for `foo = bar->x[bar→y--]`. Doing so would make the code much cleaner, but performance is priority in that spot so that would only be a good choice if it didn't affect the performance at all. – MaiaVictor Jun 22 '14 at 02:55
  • Whether there is a penalty is totally at the discretion of the compiler. You will have to try out both ways and compare. – Raymond Chen Jun 22 '14 at 02:59
  • @Viclib If that is your use case and you put it in a static function in the same `.c` file I'm fairly certain that the compiler will give you the best case performance. You aren't going to beat it by trying to out-think it, unless you have some profiling data to guide your decisions. In which case you should consider profiler-guided optimization, which will beat you again. – Jeremy West Jun 22 '14 at 03:27
  • Maybe a little offtopic, but what are guidelines in profiling C code? – MaiaVictor Jun 22 '14 at 03:29

3 Answers3

3

The answer is: it depends.

I'm currently using MSVC compiler and GCC for a project at work and my experience is that they both do a pretty good job. Furthermore, the cost of a function call in native code can be pretty small, especially in functions that do not need to be accessible outside the executable (like functions not exported in a shared library). For these functions, there is more flexibility with how the call is actually implemented.

A few things to note: it's much easier for a compiler to optimize calls to static functions. Functions with external linkage often require link time optimization since one must know how and where the function is actually called, as well as the implementation, to do much optimization or inlining. This requires examining more than one compilation unit at a time.

I would say that you should use functions where it makes sense and makes the code easier to read and maintain. In general, it is safe to assume that the cost is smaller than it would be in JavaScript. But in the end, you'd have to profile the code to say anything more precise.

UPDATE: I want to emphasize that functions can be inlined across compilation units, but this requires link-time optimization (or whole program optimization). This is supported in both GCC (https://gcc.gnu.org/wiki/LinkTimeOptimization) and MSVC (http://msdn.microsoft.com/en-us/library/0zza0de8.aspx).

These days, if you can beat the compiler by copying the body of a function and pasting it everywhere you call that function, you probably need a different compiler.

Jeremy West
  • 11,495
  • 1
  • 18
  • 25
  • Would you consider it a JavaScript flaw? – MaiaVictor Jun 22 '14 at 03:35
  • "flaw" might be a bit strong. It's a limitation of an interpreted language. To be honest, I haven't done any serious JavaScript programming in years, so I don't know what the state of current JavaScript implementations is. – Jeremy West Jun 22 '14 at 13:11
2

In general, with optimizations turned on, gcc will tend to inline short functions provided that they are defined in the same compilation unit that they are called in.

Moreover, if the calling function and called function are in different compilation units, the compiler does not have a chance to inline them regardless of what you request.

So, if you want to maximize the chance of the compiler optimizing away a function call (without manually inlining), you should define the function call in .h file or in the same c file that it is called in.

merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • Declaring the function in a `.h` file but defining it elsewhere doesn't help at all: the inlining still requires examination across compilation units. And most modern compilers are capable of optimization across compilation units anyway. – Jeremy West Jun 22 '14 at 03:16
  • @JeremyWest, I said that he has to `define` the function `.h`, not **declare**. – merlin2011 Jun 22 '14 at 07:05
1

There are no inner functions in C. Dot. So the rest of your question is kind of irrelevant.

Anyway, as of "normal" functions in C compiler may or may not inline them ( replace function invocation by its body ). If you compile your code with "optimize for size" it may decide to do not do inlining for obvious reason.

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • Not inner functions; inner loops. As in, calling `x = double(x)` inside a hot spot in JS is much slower than just writing `x = x * 2`. – MaiaVictor Jun 22 '14 at 03:00
  • In C if you want to force inlining you can define macro like: `#define double(x) (x) * 2`. Such code will be expanded in place where it will be used. – c-smile Jun 22 '14 at 03:11
  • Yes, which will blow up in your face as soon as you do anything non-trivial with it, such as the classic `#define square(x) ((x)*(x))` which then gets used as `square(x++)` to disastrous effect. – Jeremy West Jun 22 '14 at 03:23
  • Where non-trivial = non-referentially transparent! – MaiaVictor Jun 22 '14 at 04:36