Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

For C++, if you have many library headers used repeatedly in many source files, the number 1 suggestion ought to use a precompiled header (which you write yourself with commonly used library headers but none of your application headers). It was mentioned on that page but a bit buried and OP replaced a whole dependency before trying it.

I don't think the same thing would work for Rust because, unlike C++, it doesn't need to constantly reparse files in its depedencies - essentially it already has them automatically. C++ is aiming to move that way in future with modules.

Edit: I just tried turning off precompiled header on one of our larger programs that's heavy on Boost and a couple of our other libraries, and it increased build time from 2:16 to 10:52 (that's minutes and seconds) after fixing a few missing #includes that were covered by the precompiled header.



It seems to depend a lot on the particular compiler. I know that in the past, precompiled headers made a huge difference with MSVC (and maybe they still do, but I haven't used it in some years at this point).

Today, I have a medium-sized c++ project that uses Linux, gcc 9.2 and boost and I have yet to find any combination of headers that I can put in the precompiled header file and see any reduction in compile times, either for a full build or an incremental build.


Hmm, that is interesting... You're absolutely right, the program I was compiling is a Visual Studio program. (The code is actually cross-platform, partly thanks to the use of Boost, but for historical reasons it only has a Windows build system in the form of Visual Studio projects.) I'd definitely like to try my experiment again with GCC or clang at some point.


Precompiled headers are a workaround when you can't modularize your project / headers files. But to use them you commit to the wrong way, including everything the same way everywhere.... what you should do is include only minimal stuff from the headers, and prefer to include most dependencies only in implementation.


> Precompiled headers are a workaround when you can't modularize your project / headers files.

This is technically true but misleading - the whole nature of C++ means that you can't modularize your project / headers in a way that avoids transitively including lots of headers. There's two reasons for this:

* Lots of Boost (and other library) types are vocabulary types - that's often the whole point of using them in the first place. If my class has a public method that returns a boost::optional<T> or boost::flat_map<K, V> then there's no way to avoid transitively including the relevant Boost headers in my header files.

* Lots of Boost stuff is templated so the implementation has to go in the header, which means the transitive dependencies on other parts of Boost have to be included in the header, even they're only used in the implementation of the Boost class that you're directly use. The heavy templating is a result of the previous point - vocabulary types often need to be templated in order to be useful in many different situations.


You just have to use forward declaration headers in you headers. For your two examples :

-> flat_map: https://www.boost.org/doc/libs/1_67_0/boost/container/contai...

-> optional: https://www.boost.org/doc/libs/1_67_0/boost/optional/optiona...


That's true, but it creates an annoying extra burden on anyone that calls those functions to include the full-fat library header themselves. Since they might simply write `auto x = my_obj.returns_optional()`, it might not even be that obvious they need to add that header.

Plus, of course, once they have added that header to their file, that header is included in their file, if you see what I mean, so it may not actually save compilation time while still adding coding effort. Really, I think that technique is only useful if you're only referring to those types (a) in private functions, and (b) by reference or pointer. By the time it's a public function, you have a responsibility to include the full library header in your header file.


Which is why many companies shy away from Boost and from libraries that do clever template meta-programming.


Indeed, but it's just ignorance driving that. You end up with three choices:

* Use libraries like Boost and waste developer time waiting for compilation.

* Avoid libraries like Boost and waste developer time re-implementing functionality (but then you have the same problem anyway) or suffering from not having that functionality available to them.

* Use libraries like Boost and spend a small one-time developer cost turning on precompiled header files in your build system.


Boost is a pain to compile, sure, but a bit of a necessary evil for anything C++. Threadrippers are dirt cheap compared to developer time and compilation is embarrassingly parallel. Just by devs 32-core boxes and be done with it.


Except that on the projects I have been consulting, the last time I actually coded on a desktop was around 2006. And most customers nowadays just have IT throw a VM to externals.

You're not getting Threadrippers from these kind of companies.


So things would be better if Boost.Signals2 weren't header-only? Makes sense.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: