Skip to content

tracing_core::dispatcher is repeatedly monomorphised in the downstream crate #783

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

Closed
matklad opened this issue Jul 7, 2020 · 4 comments · Fixed by #787
Closed

tracing_core::dispatcher is repeatedly monomorphised in the downstream crate #783

matklad opened this issue Jul 7, 2020 · 4 comments · Fixed by #787

Comments

@matklad
Copy link
Contributor

matklad commented Jul 7, 2020

(meta: sorry for ignoring the template, I just want to quickly pen down an observation, feel free to ignore the issue!)

In rust-analyzer, I've noticed that tracing is pretty "hot" in terms of cargo llvm-lines. For our type-checking code I get:

  Lines           Copies        Function name
  -----           ------        -------------
  1687176 (100%)  52708 (100%)  (TOTAL)
    59685 (3.5%)    115 (0.2%)  alloc::raw_vec::RawVec<T,A>::grow
    55452 (3.3%)    474 (0.9%)  tracing_core::dispatcher::get_default::{{closure}}
    41932 (2.5%)    333 (0.6%)  core::iter::traits::iterator::Iterator::try_fold
    40152 (2.4%)   3972 (7.5%)  core::ptr::drop_in_place
    38954 (2.3%)    553 (1.0%)  core::option::Option<T>::map
    33309 (2.0%)    483 (0.9%)  core::result::Result<T,E>::map_err

Three points of interest here:

  • tracing is hot in absolute terms
  • there's substantiational amount of monomorphisation happening (474 instances)
  • monomorphisation happens in the downstream crate, that is, there's no separate compilation.

Note that rust-analyzer doesn't use tracing directly itself, it comes from chalk I believe (but impacts our compile times, and not chalk compile times, due to the last bullet).

@davidbarsky
Copy link
Member

davidbarsky commented Jul 7, 2020

Thanks for bringing this to our attention! I did some preliminary digging, I fully expect that @hawkw will correct me :)

I suspect that the get_default monomorphizations are coming from one of two places:

If the monomorphized code is coming from the macros, I'm not entirely sure how to change that at the moment; I think Eliza will be able to say with greater confidence as to what's up.

In the meantime, I'm going to try to swap out env-logger in rust-analzyer with tracing-subscriber to see if the LLVM line count goes down.

@davidbarsky
Copy link
Member

Over Zulip, @matklad told me:

For salsa, the percentage for the top function was also low (5 or something like this), but the knock-down effect added up to 5x [compilation speed slowdowns]. This probably won't be the case for tracing (as fewer code should be called inside monorphised stuff)

@hawkw
Copy link
Member

hawkw commented Jul 7, 2020

  • monomorphisation happens in the downstream crate, that is, there's no separate compilation.

Ah, yup, this is because all the invocations are inside a macro.

It seems like a potential solution to this would be to have a function like

fn is_enabled(meta: &Metadata<_>) -> bool {
    dispatcher::get_default(|current| current.enabled(meta)
}

for the most common monomorphizations that occur inside the macros. That way, the same closure is only monomorphized once inside of tracing rather than in every downstream crate.

This should actually be a pretty simple fix, so we can try it out and see if it has a significant impact on compile times.

@davidbarsky
Copy link
Member

@matklad I've opened an PR that attempts to address this issue: #787.

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

Successfully merging a pull request may close this issue.

3 participants