I have a huge problem. I have a common library, that is used all across my project. This library intensively uses boost.spirit
and boost.fusion
. Unfortunately, the library is approx. 700Mb in size. All the boost.spirit
-heavy code is used and it works well. What steps can be done to reduce its output size? Is there is a tool that can help to determine what template instantiations waste most of the space?
At first, I decided to move all spirit-aware code to cpp files. Second, I will try different compiler flags to optimize for size. I don't know what else to do.
Update(details)
I'm using GNU toolchain. Huge library is actually a static library. Executable, that uses this 700Mb library is 200Mb in size. At least half of the code is in *.h files. Some boost.spirit
grammars (very template heavy thing) is also located in *.h files.
Cheers!
The short answer is no. Indirectly, however, they can slow things down under a few circumstances. In particular, each instantiation of a template (normally) produces code that's separate and unique from other instantiations.
Since the compiler generates additional code for each template type, indiscriminate use of templates can lead to code bloat, resulting in larger executables.
Templates are slow (to build) For example, the supplied vector type in C++ is a template type, meaning that we can store multiple different types of objects in the same data structure. This allows us to seperate two concerns: the way the object is stored and how it works, which partitions complexity for our minds.
Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues which can be used with any arbitrary type. C++ templates provide a way to reuse source code as opposed to inheritance and composition which provides a way to reuse object code.
Moving the spirit aware code to .cpp
files is a good first step, it might be incomplete though as you mention having spirit grammar in header files.
Make sure than none of the grammar / rules are ever exported outside the library. If you have the typical include
/src
directories, then move those files (even if headers) within the src
directory.
Mark all those symbols as internal to the library. They should not be accessible from outside the library at all. There are specific pragmas/attributes depending on your compiler, on gcc lookup the visibility attribute: __attribute__ ((visibility ("internal")))
. This helps the compiler optimizing them accordingly, notably a compiler may emit the code of a function even if it inlines it at a given call site, just in case this function address is taken. With internal visibility however, since it knows the code will not leave the object, it may elide the function.
I seem to remember a flag to fuse identical function bodies but cannot seem to find again...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With