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

Huge performance regression in rustdoc between 1/28 and 2/25 nightlies #58849

Closed
jdm opened this issue Mar 1, 2019 · 38 comments
Closed

Huge performance regression in rustdoc between 1/28 and 2/25 nightlies #58849

jdm opened this issue Mar 1, 2019 · 38 comments
Assignees
Labels
C-bug Category: This is a bug. I-slow Issue: Problems and improvements with respect to performance of generated code. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Comments

@jdm
Copy link
Contributor

jdm commented Mar 1, 2019

When using the 1/28 Rust nightly for a Servo CI job on linux, the job that does a variety of builds and unit tests as well as generates docs for every single dependency took 20 minutes total. After updating to the 2/25 nightly, just the doc generation by itself takes 37 minutes, often causing our CI limit of 60 minutes to be exceeded.

@jdm jdm added I-slow Issue: Problems and improvements with respect to performance of generated code. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Mar 1, 2019
@jdm
Copy link
Contributor Author

jdm commented Mar 1, 2019

Looks like the doc generation used to take 6m 28s.

@euclio
Copy link
Contributor

euclio commented Mar 1, 2019

I added a new docs pass to check codeblock syntax a few days before the 1/28 nightly. The timing's a little off, but you could try running rustdoc without the check-code-block-syntax pass to see if that makes up the difference.

Never mind, that pass is present in the 1/28 nightly.

@Manishearth
Copy link
Member

cc @QuietMisdreavus

@Mark-Simulacrum
Copy link
Member

It looks like the number of patches landing in master between those two nightlies is actually fairly small when constraining to just src/librustdoc. I might have messed this up though.

f573049 Auto merge of #58232 - ljedrz:HirIdification_continued, r=Zoxc
aadbc45 Auto merge of #57051 - Eijebong:parking_lot, r=nikomatsakis
fcccf06 Auto merge of #56514 - ollie27:rustdoc_test_libdir, r=QuietMisdreavus
32471f7 Auto merge of #58503 - varkor:const-generics-hir, r=petrochenkov
b244f61 Auto merge of #58341 - alexreg:cosmetic-2-doc-comments, r=steveklabnik
0e5a209 Auto merge of #58058 - QuietMisdreavus:use-attr, r=GuillaumeGomez
4b1e39b Auto merge of #57851 - Aaron1011:fix/clean-lifetime, r=GuillaumeGomez

@GuillaumeGomez
Copy link
Member

It's very certainly because of my minification process. Although, I didn't expect it to have a noticeable impact...

@QuietMisdreavus
Copy link
Member

The only minifier change that landed into rustdoc between those dates was #57884. The minifier was actually in place before then.

@Manishearth
Copy link
Member

This may actually be a regression in quote/proc-macro2.

I'm not yet sure if this is the thing causing long doc builds (some things in our server build history disagree with this hypothesis), but our mozjs_sys crate hits a ton of intra-doc-links failures in jsapi.rs, a bindgen-generated file. Normally this is fine, but on some versions of proc-macro2 bindgen is outputting a file that's basically a single giant line (+ some headers). The intra doc link failures have a field day with this, printing out the entire (already giant) file for each warning. There are a lot of such warnings because the autogenerated documentation has things like [[Get]] in it (used in JS specs to talk about properties/methods/slots). This is probably a lot of work for rustc (since it also has to do span computation), as well as a lot of IO traffic, slowing everything down.

@Manishearth
Copy link
Member

Manishearth commented Mar 9, 2019

I've narrowed down the regression range to between 2019-02-07 and 2019-02-10

@Manishearth
Copy link
Member

No, the mozjs_sys issues are not the problem. They started becoming a problem at some point, but the commit that did the rust upgrade does not have a giant log, and still takes 55minutes to build

@Manishearth
Copy link
Member

These are all the PRs landing in master in that range

d173180 Auto merge of #58266 - GuillaumeGomez:rollup, r=GuillaumeGomez
ad43389 Auto merge of #58010 - Zoxc:parallel-passes, r=michaelwoerister
626e74d Auto merge of #58254 - kennytm:rollup, r=kennytm
825f355 Auto merge of #57998 - niklasf:align-enum, r=nagisa
1efdda1 Auto merge of #58125 - taiki-e:libsyntax-2018, r=Centril
ff9158c Auto merge of #58224 - pietroalbini:revert-appveyor-debug, r=alexcrichton

The first rollup contains a lot of rustdoc PRs.

@Manishearth
Copy link
Member

It's probably either #58143 or #57884 from #58266 , verifying that the problematic commit is indeed the rollup (sadly we don't store travis builds for rollup contents)

Servo does have crates with a ton of items in them, so we may be hitting ranges where algorithmic complexity actually matters.

@Manishearth
Copy link
Member

Confirmed, the perf regression is inside #58266

@Manishearth
Copy link
Member

The regression is caused by #57884 cc @GuillaumeGomez

Unsure what's casing it so far.

@Manishearth
Copy link
Member

I suspect it's just that we have some truly giant crates (see https://doc.servo.org/script/) and we're hitting some pathological case

@GuillaumeGomez
Copy link
Member

The problem is that I currently re-read the JS a few times. It's worth taking a look at this giant crate now to see how I can improve it (I never focused on speed for it after all).

@Manishearth
Copy link
Member

@GuillaumeGomez Is the number of times you reread the JS dependent on the size of the crate?

I'm not yet sure if it is indeed this crate causing this problem, but the crate in question is Servo's script crate. It may also just be the sum total of all the crates being slow.

@GuillaumeGomez
Copy link
Member

Potentially. I'll take a look as soon as I can.

@Manishearth
Copy link
Member

It seems like the filesize for the generated docs is also just huge. It took forever to delete target/doc. I'm rebuilding it to see the difference against --disable-minification.

@Manishearth
Copy link
Member

Nope, they're roughly the same size.

@GuillaumeGomez
Copy link
Member

And what the rendering time difference?

@Manishearth
Copy link
Member

--disable-minification takes a couple minutes, without it it takes 70

bors-servo pushed a commit to servo/servo that referenced this issue Mar 11, 2019
Move docs build back into tidy+unit builder, disable minification

According to rust-lang/rust#58849 the rustdoc performance regression is due to a minification change. Disabling minification fixes it temporarily.

Minification is a decent chunk of execution time for us even for normal doc builds so we may actually want to just keep it this way.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23014)
<!-- Reviewable:end -->
@Manishearth
Copy link
Member

With --disable-minification the doc search no longer works

https://doc.servo.org/script/?search=websocket gives

ReferenceError: N is not defined

@jonas-schievink jonas-schievink added the regression-from-stable-to-beta Performance or correctness regression from stable to beta. label Apr 16, 2019
jonas-schievink added a commit to jonas-schievink/rubble that referenced this issue Apr 16, 2019
@jamesmunns
Copy link
Member

jamesmunns commented Apr 17, 2019

I think I've run into this too, I'm seeing a 3x slowdown for an embedded crate (pretty full of generated code). In case this is a useful repro case:

james@archx1c6g ➜  /tmp git clone https://github.com/nrf-rs/nrf52832-pac
Cloning into 'nrf52832-pac'...
james@archx1c6g ➜  /tmp cd nrf52832-pac

james@archx1c6g ➜  nrf52832-pac git:(master) time cargo +1.33.0 doc --open
   Compiling semver-parser v0.7.0
   ...
 Documenting nrf52832-pac v0.6.0 (/tmp/nrf52832-pac)
    Finished dev [unoptimized + debuginfo] target(s) in 30.98s
     Opening /tmp/nrf52832-pac/target/doc/nrf52832_pac/index.html
cargo +1.33.0 doc --open  34.23s user 2.07s system 116% cpu 31.205 total

james@archx1c6g ➜  nrf52832-pac git:(master) ✗ cargo clean

james@archx1c6g ➜  nrf52832-pac git:(master) ✗ time cargo +1.34.0 doc --open
   Compiling semver-parser v0.7.0
   ...
    Finished dev [unoptimized + debuginfo] target(s) in 1m 39s
     Opening /tmp/nrf52832-pac/target/doc/nrf52832_pac/index.html
cargo +1.34.0 doc --open  102.90s user 1.71s system 104% cpu 1:39.75 total

Edit: This is specifically a stable-to-stable perf regression between 1.33.0 and 1.34.0.

@jonas-schievink jonas-schievink added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. C-bug Category: This is a bug. I-nominated and removed regression-from-stable-to-beta Performance or correctness regression from stable to beta. labels Apr 17, 2019
@matthewkmayer
Copy link

Also seeing a large performance regression from 1.33.0 to 1.34.0 in Rusoto. We document a lot of crates (146 right now) and documentation job time went from 16 minutes to timing out at more than 50 minutes.

Our current workaround is to use 1.33.0 to document our code. This will stop working as soon as we adopt anything from the 1.34.0 release.

Anything we can test to help fix this?

@Manishearth
Copy link
Member

Can we revert the minification update PR? @GuillaumeGomez

@GuillaumeGomez
Copy link
Member

@Manishearth It made a first performance improvement. Removing it doesn't seem to be a good idea...

@jamesmunns
Copy link
Member

I took a flamegraph of the problematic sections of nrf52832-pac, using cargo-flamegraph.

rustdoc flamegraph

I ran cargo +beta doc (the regression also exists there) once to build all deps, then re-ran the specific slow file through flamegraph. My command was this:

flamegraph -o rustdoc.svg /home/james/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/bin/rustdoc --edition=2018 --crate-name nrf52832_pac src/lib.rs --color always -o /tmp/nrf52832-pac/target/doc -L dependency=/tmp/nrf52832-pac/target/debug/deps --extern bare_metal=/tmp/nrf52832-pac/target/debug/deps/libbare_metal-77e06d3286078ba3.rmeta --extern cortex_m=/tmp/nrf52832-pac/target/debug/deps/libcortex_m-3b084aea88ac1290.rmeta --extern vcell=/tmp/nrf52832-pac/target/debug/deps/libvcell-28d9c41f1ae25f64.rmeta

Specifically, __memmove_avx_unaligned_erms is taking 75% of the runtime, with the call graph looking something like:

  • rustdoc::html::render::run
    • rustdoc::html::render::write_shared
      *write_minify_replacerstd::fs::File
      * apply
      * { { closure }}
      * aggregate_strings_into_array_with_separation
      * aggregate_strings_into_array_inner
      * insert<minifier::js::token::Token
      * copy<minifier::js:token::Token
      * __memmove_avx_unaligned_erms

In this whole call stack, almost all time is spent in the bottom item.

@Manishearth
Copy link
Member

@GuillaumeGomez I don't understand what you mean by that comment.

If it made an improvement but also had extremely adverse effects on some crates, it should be fixed or reverted. That's not a performance improvement.

@GuillaumeGomez
Copy link
Member

@Manishearth: I meant by my comment that the situation was worse before my last changes.

@jamesmunns: Thanks! That'll help me a lot!

@Manishearth
Copy link
Member

I meant by my comment that the situation was worse before my last changes.

From my measurements on servo and the other measurement in this thread, this is definitely not universally true, and the cases where it's not true it's super bad.

@GuillaumeGomez GuillaumeGomez self-assigned this Apr 18, 2019
@GuillaumeGomez
Copy link
Member

Strange since I removed a few iterations over the full JS tokens... I'll check soon.

@Manishearth
Copy link
Member

Any updates on this? I think we should do a more careful performance measurement here, perf updates that make things worse for a lot of crates should be done carefully.

@euclio
Copy link
Contributor

euclio commented Nov 26, 2019

I believe the plan is to remove minification entirely, as discussed in #56359.

@GuillaumeGomez
Copy link
Member

Or at least on the search-index.js file. Doesn't hurt to have it on the other files.

@jonas-schievink
Copy link
Contributor

Was this fixed by #66828?

@jamesmunns
Copy link
Member

At least with a relevantly recent nightly, this is back down to within the rough area of 1.33.0.

active toolchain
----------------

nightly-x86_64-unknown-linux-gnu (default)
rustc 1.42.0-nightly (c5840f9d2 2020-01-03)
 Documenting nrf52832-pac v0.9.0 (/tmp/nrf52832-pac)
    Finished dev [unoptimized + debuginfo] target(s) in 32.15s
     Opening /tmp/.cargo-build-cache/doc/nrf52832_pac/index.html
cargo +nightly doc --open  36.66s user 2.46s system 120% cpu 32.519 total

@GuillaumeGomez
Copy link
Member

I guess it can be closed then!

mrobinson added a commit to mrobinson/servo that referenced this issue Dec 13, 2023
Disable isn't possible for non-nightly versions of Rust, so this is
currently breaking the doc build. In addition, it seems that the
original issue that triggered this change [^1] is now fixed.

[^1]: rust-lang/rust#58849
github-merge-queue bot pushed a commit to servo/servo that referenced this issue Dec 13, 2023
Disable isn't possible for non-nightly versions of Rust, so this is
currently breaking the doc build. In addition, it seems that the
original issue that triggered this change [^1] is now fixed.

[^1]: rust-lang/rust#58849
github-merge-queue bot pushed a commit to servo/servo that referenced this issue Dec 13, 2023
Disable isn't possible for non-nightly versions of Rust, so this is
currently breaking the doc build. In addition, it seems that the
original issue that triggered this change [^1] is now fixed.

[^1]: rust-lang/rust#58849
github-merge-queue bot pushed a commit to servo/servo that referenced this issue Dec 13, 2023
Disable isn't possible for non-nightly versions of Rust, so this is
currently breaking the doc build. In addition, it seems that the
original issue that triggered this change [^1] is now fixed.

[^1]: rust-lang/rust#58849
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-slow Issue: Problems and improvements with respect to performance of generated code. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants