Skip to content
This repository has been archived by the owner on Sep 12, 2018. It is now read-only.

Avoid monomorphizing large functions multiple times #774

Open
thomcc opened this issue Jun 28, 2018 · 1 comment
Open

Avoid monomorphizing large functions multiple times #774

thomcc opened this issue Jun 28, 2018 · 1 comment
Labels

Comments

@thomcc
Copy link
Contributor

thomcc commented Jun 28, 2018

Related to #772.

Most of this is taken from https://gist.github.com/thomcc/09f48b222e4fdf69c43479ee65daf2ab (which is taken from a list of top functions of mentat_ffi when compiled as a cdylib)

If you look at that listing there are a number of duplicated functions, which are almost all going to be a result of the function being monomorphized multiple times. We should avoid these for anything large.

IntoIterator seems like a frequent offender here. In other code ,stuff like Into and AsRef are often responsible.

  • transact_entities is duplicated at least twice and accounts for over 40kb according to cargo-bloat, , and probably could just take a Vec<Entity<V>> (this is still generic, but in practice TransactableValue is only ever ValueAndSpan AFAICT, so it will only be monomorphized a single time).
  • transact_simple_terms is likely the cause of the previous's bloat, and if it were only called with a single type it would likely not be getting inlined into transact_entities. Note also that we could fairly easily avoid the generic argument, since it's just used as something to pass to Generation::from.
  • project_elements should probably just take a Vec,

There are probably more that just get inlined too and contribute to their caller getting bigger. There's a balance between this and performance though, so it's not 100% cut and dry, but for huge functions the overhead of e.g. collecting an iterator into a vector seems likely to be negligible.

@ncalexan ncalexan added the size label Jun 28, 2018
@ncalexan
Copy link
Member

This is very interesting, @thomcc. I quite like the IntoIterator pattern, but if it's costing us huge amounts of duplicated code that's not good. Does the impl Trait or Box<Iter> pattern help with the code bloat, perhaps at the cost of runtime performance? (For most of the things we're doing we don't care about the input iterator performance at all; it's dwarfed by the processing overhead.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants