Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

heavy use of polymorphism results in long compiles #388

Open
cwlbraa opened this issue Mar 23, 2017 · 6 comments
Open

heavy use of polymorphism results in long compiles #388

cwlbraa opened this issue Mar 23, 2017 · 6 comments
Milestone

Comments

@cwlbraa
Copy link

cwlbraa commented Mar 23, 2017

via metaprogramming, a project I'm working on has a very large number of cereal message types registered (~700) and we've started to notice that each call to CEREAL_REGISTER_TYPE incurs a heavy compile time cost, anywhere from 0.5 - 0.8s per invocation. Are you aware of this? Is there any way to shave that time down?

@AzothAmmo
Copy link
Contributor

This is a bit of a tricky issue to optimize as it is difficult to get actionable information from the compiler about what takes time during compilation.

The way polymorphic support currently works is based on the boost implementation and is designed to simplify the process for users, which may come at a cost for compilation time. polymorphic registration currently does not require knowledge of archives and types simultaneously - cereal handles the binding of types to available archives.

In a nutshell, specific cereal archives create an overloaded definition of a special function (instantiate_polymorphic_binding) that is templated on a type. This overload is designed to never actually have highest precedence when invoked, however, due to some black magic, the return types for the unpicked overloads will all be instantiated. It is these return types that actually create all of the metadata needed to perform polymorphic serialization.

When you go and register your polymorphic type, it tries to invoke this special function (remember it doesn't know about any archives), and must find the best possible overload of the function.

Every archive you have included creates a type templated overload of this function. So when you register one type, it creates NUM_ARCHIVES new overloads that must be checked. This isn't a big deal for a few types, but as you've seen when the number of types is large, every registration is both adding to the number of overloads and then searching through that entire list for the best candidate.

I'm not sure if there is a good way to optimize this using the current interface. However, it would likely be significantly faster if you were willing to individually tie types and archives together. This would remove the entire overload process from registration, meaning you'd do something like:

CEREAL_REGISTER_TYPE_WITH_ARCHIVE(myType, cereal::BinaryInputArchive, cereal::BinaryOutputArchive)

or something similar.

@cwlbraa
Copy link
Author

cwlbraa commented Mar 27, 2017

I am very much willing, I'll have to give that a shot!

@AzothAmmo
Copy link
Contributor

I just want to note that this feature is not actually in cereal right now, but could be easily added.

@cwlbraa
Copy link
Author

cwlbraa commented Mar 28, 2017

aw man you had me so excited

@BotellaA
Copy link

Is there any news on this topic? My compilation time is huge and uses a lot of memory too.

@BotellaA
Copy link

BotellaA commented Jan 2, 2019

@AzothAmmo Is this feature still plan for 1.2.3?

@AzothAmmo AzothAmmo modified the milestones: v1.2.3, v1.3.0 Oct 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants