Ever had to put up with long compile times? If you've written software using compiled languages for a while, then I bet you have. Sooner or later, a project's size grows to the point where an increasing amount of your time is spent waiting for the compiler to finish so that you can test your code. Here are a few ways you can get the compile time back down:
Buy a faster machine ;-)
Yes, one of the easiest ways is to get a more powerful computer... until you have to pay for it, that is. A more powerful machine with a very fast hard-drive will make a difference.
Your computer likely has multiple cores. So, how about putting all of them to use when compiling? It's very easy to do with makefiles. Simply add a -j<n> parameter, where <n> is the number of cores you have. For example:
his will start <n> build processes, enabling your project to be built faster. In scripts you can get the number of cores using the nproc command, e.g.:
There are some complications with using parallel make/build, but I'll leave those for some other time.
Eliminate Unnecessary Includes
If a faster machine and parallel builds aren't enough, then reducing compile time takes more effort. You'll need to go through your code and eliminate all unnecessary includes. What this does, is reduce the number of files that get recompiled every time you change a header. This can be a big time saver.
The worst case is when you have a header file that's included in all source files. In that case, one change to that header results in a full rebuild of the entire project.
Eliminate Unnecessary Includes Part 2
#include statements in header files are a special problem. They can build an entire web of #includes, meaning that including a single header file sucks in many many more. Any change to header files inside that web of includes could trigger a huge rebuild.
In the video I give the example of the HTTPConnectionsList class in HTTPConnection.h. It has a pointer to an EventManager (the class that handles the event loop). However, code that uses the HTTPConnection does NOT need access to the EventManager. So, we can add a class declaration to the top of the header file, e.g.:
Then, we can move the #include "EventManager.h" statement to HTTPConnection.cpp. One more include eliminated. Now we can modify EventManager.h without triggering a rebuild of every source file that uses an HTTPConnection (which is every HTTP request handler for ZitaFTP's web-based GUI).
If the above isn't enough, then here are a few more:
The PImpl Paradigm
Here, you create a wrapper class with a Pointer to an Implementation class. This completely separates the internal implementation from any code that uses it. While this can reduce header file dependencies, I suggest using it with caution. PImpl doubles the number of source files used because you have both the implementation and a wrapper. You also have double-work, since all public methods need to be duplicated in the wrapper. There's also a small runtime overhead.
PImpl can be effective, but only use it when it's actually needed.
PreCompiled Headers (PCH)
I've never really bothered with PCH, because they have all sorts of restrictions. And, with GCC they don't have much impact on the compile time of C++ code. I've been told that they're more effective with Microsoft's Visual Studio. However, most of my work is done with GCC.