Code gen on generic struct

pub struct Foo<T> { ... }

impl <T> Foo<T> {
  pub fn func_does_not_depend_on_T(...) {
  }
}

Is func_does_not_depend_on_T code-generated once per every T used ? If so, does it make sense to (for compile time), move func_does_not_depend_on_T to a non-generic environment? (Or is this borderline stupid micro optimization) ?

Thanks!

EDIT: it actually generate multiple times. see below

if it's truly not dependent on T, notably, it doesn't use Self, then it is not a generic function, and I don't think it will be instantiated multiple times.

monomophization only applies to generic functions.

It will be generated multiple times:

However, LLVM optimizations can remove identical functions.

You can use an inner function to debloat traits:

  pub fn func_does_not_depend_on_T() {
    fn this_one_truly_does_not() {}
    this_one_truly_does_not()
  }
2 Likes

As far as I know, it's actually worse than that... Say you use a Foo<u32> in your code, the compiler won't just generate a single instantiation of func_does_not_depend_on_T, it'll generate a new copy of Foo::<u32>:: func_does_not_depend_on_T for every codegen unit that happens to use a Foo<u32>.

When you consider that the compiler breaks your crate up into multiple codegen units so machine code can be generated and optimised in parallel, that means you might compile Foo<u32> several times.

That's one of the reasons the standard library uses the inner function pattern all over the place:

1 Like