1

I have been told by some colleagues (who are smart than me) that moving implementation (definition) outside header can reduce compile time in some cases - I should do it in most case.

After a lot of refactoring, I believe it is true.

Now I plan to move implementation of very simple functions too. (.h -> .cpp)

void f(int index){
    return database[index*2];  //<--- contain trivial algorithm like this
}

Question

What are the factors to determine how much the benefit?

More specifically :-

  1. Does the amount of time used to compile saved depends on

    • amount of characters (exclude comment) I moved to .cpp or ...

    • complexity (not mean O(n) here) of algorithm of function or ...

    • something else ?

  2. Should I move definition of such simple functions to .cpp?
    (concern only performance and compile time, not concern maintainability or readability)

Edit: detailed example

Consider this code.

B.h :-

class B{
    public: static void fb(){  
        //some complex code (e.g. 1000 lines)
    }
};

C.h :-

#include "B.h"
class C{
    static void fc();
};

C.cpp contains implementation of fc()

D.h :-

#include "B.h"
class D{
    static void fd();
};

D.cpp contains implementation of fd()

Before moving definition of fb, the compiler will have to compile large code of B.h for C.cpp and D.cpp.

After moving definition of fb to b.cpp, I think C.cpp and D.cpp will be a lot easier to compile.

javaLover
  • 6,347
  • 2
  • 22
  • 67

3 Answers3

3

What are the factors to determine how much the benefit?

The major factor for reduction of compile time depends on how many other translation units include that header with the inlined code. The other factors you mentioned are merely irrelevant.

If you change something in the definition many more files would need to be recompiled, than if you change the definition only in a single .cpp file.

  1. Should I move definition of such simple functions to .cpp? (concern only performance and compile time, not concern maintainability or readability)

No, what I said above refers to non trivial stuff. If you have such simple function definition and it's unlikely it will be changed in future, you can leave it in the header file.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • For *such* a trivial function, I would keep it in the header. It is unlikely that you are going to make changes there. Similarly "size" methods in a container should be inline. – Martin Bonner supports Monica Dec 22 '16 at 09:54
  • @Martin Agreed. For trivial stuff that's unlikely to be changed I'd do the same. I tried to answer OP's confusions about the overall impact and what their co-workers referred to (most probably). – πάντα ῥεῖ Dec 22 '16 at 10:00
  • I think there are some performance gain (compiler) in the case of detailed example (I just added). Do you think the benefit is not much? Do I miss something? – javaLover Dec 22 '16 at 10:05
  • @javaLover IMO the more detailed sample you gave now, pretty much resembles what I already stated. – πάντα ῥεῖ Dec 22 '16 at 10:08
  • 1
    @javaLover : In your detailed example, yes a clean rebuild from scratch will be quicker if `B::fb` is defined in b.cpp because `B::fb` only has to parsed once rather than twice. The *big* difference though, is that when you change `B::fb`, you will need to recompile b.cpp, rather than both c.cpp and d.cpp. (and you are quite likely to change a 1000 line function). – Martin Bonner supports Monica Dec 22 '16 at 10:12
  • @Martin Bonner That clarifies a lot. Thank for beginner-friendly description! – javaLover Dec 22 '16 at 10:17
  • 1
    @javaLover To add up on Martins comment. The effect for from scratch builds will be minimal for trivial functions. – πάντα ῥεῖ Dec 22 '16 at 10:19
3

The answer can be simple and less simple.

Simple answer:

  • put implementation of non-trivial function in the source files, there are many advantages to this, not just compilation time.

  • Leave implementation of trivial function in the header file and make non-member-functions inline, the compilation time will not differ significantly and there are even better optimization possibilities.

Less simple:

  • Putting non-trivial functions in source file is done specifically so the header files, which are like interfaces to the code, are more readable, don't have to contain all the includes needed for implementation, can prevent mutual cycle issues and on top have better compilation times.

  • Putting trivial functions in the header file let the compiler do better optimisation during compile-time (as opposed to link-time) because it knows at the calling point what the function does, so it knows better when to inline and reorder code (see here for link-time optimization).

  • Templates should still always be in header files. for some complex functions, the non-template part may be factored out and put in a source file, but this can be fiddly.

  • For encapsulation reasons, it may be better to declare helper functions and helper classes in the source file completely.

  • When using pimpl-constructs, the trivial delegation functions, must be in the source file because only there, the pimpl is fully known.

So in the end ordering the code can cause better compilation times, but that shouldn't be the main reason.

Community
  • 1
  • 1
stefaanv
  • 14,072
  • 2
  • 31
  • 53
  • _"Templates should still always be in header files."_ They _must_ appear in header files. – πάντα ῥεῖ Dec 22 '16 at 10:31
  • @πάντα ῥεῖ I faintly remember that it can be moved out with some major difficulty. (known T) I don't remember exactly how to, may be ... because it is too inconvenient. – javaLover Dec 22 '16 at 10:32
  • "... can cause better compilation times, _but that shouldn't be the main reason_" +1 for that. Compile time should almost never be the reason for choosing one way of writing code over another. – Allison Lock Dec 22 '16 at 11:16
0

If you call this function which's body is in .h , it will get reference to your #include's in order to find it, because #include gives only a reference.

It will be easier for the compiler if your function's body is in .cpp

I suggest you check this out. It helped me too.

What techniques can be used to speed up C++ compilation times?

Community
  • 1
  • 1
Theo.Fanis
  • 444
  • 6
  • 15
  • What do you mean with _reference_? Declarations? – πάντα ῥεῖ Dec 22 '16 at 10:22
  • Yes, that is a good link, it helped me too. May you provide some reference / link / evident / document to support the statement "It will be easier for the compiler if your function's body is in .cpp" ? – javaLover Dec 22 '16 at 10:22
  • 1
    @javaLover They probably meant the same as what Martin has stated. The compiler needs to parse the code only once. – πάντα ῥεῖ Dec 22 '16 at 10:23
  • @πάνταῥεῖ I mean that the code that is in header files will be included-referenced as many times as your number of .cpp file's – Theo.Fanis Dec 22 '16 at 10:27