diff options
| author | bors <bors@rust-lang.org> | 2021-03-22 06:45:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-03-22 06:45:33 +0000 |
| commit | 2b8fbe6b0b6db7960828bd2c9a50e52c9a5d0aef (patch) | |
| tree | 92d9b94cd437e9e7ca01080b10e87d0475444cfb /src/librustdoc/html | |
| parent | 142c831861ba5a995fd9de99198e7f6074b6b400 (diff) | |
| parent | 1e6d8495ba63255407ebea058f2194b65ccc307d (diff) | |
| download | rust-2b8fbe6b0b6db7960828bd2c9a50e52c9a5d0aef.tar.gz rust-2b8fbe6b0b6db7960828bd2c9a50e52c9a5d0aef.zip | |
Auto merge of #82855 - jyn514:no-temporaries, r=GuillaumeGomez
Avoid temporary allocations in `render_assoc_item` `render_assoc_item` came up as very hot in a profile of rustdoc on `bevy`. This avoids some temporary allocations just to calculate the length of the header. This should be a strict improvement, since all string formatting was done twice before. cc #82845
Diffstat (limited to 'src/librustdoc/html')
| -rw-r--r-- | src/librustdoc/html/format.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 44 |
2 files changed, 30 insertions, 18 deletions
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index bea0e75832c..60106f3b7ae 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -105,6 +105,10 @@ impl Buffer { crate fn is_for_html(&self) -> bool { self.for_html } + + crate fn reserve(&mut self, additional: usize) { + self.buffer.reserve(additional) + } } /// Wrapper struct for properly emitting a function or method declaration. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 66c47f14655..128eac8cb0a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1009,18 +1009,25 @@ fn render_assoc_item( href(did, cx.cache()).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor) } }; - let mut header_len = format!( - "{}{}{}{}{}{:#}fn {}{:#}", - meth.visibility.print_with_space(cx.tcx(), meth.def_id, cx.cache()), - header.constness.print_with_space(), - header.asyncness.print_with_space(), - header.unsafety.print_with_space(), - print_default_space(meth.is_default()), - print_abi_with_space(header.abi), - name, - g.print(cx.cache()) - ) - .len(); + let tcx = cx.tcx(); + let vis = meth.visibility.print_with_space(tcx, meth.def_id, cx.cache()).to_string(); + let constness = header.constness.print_with_space(); + let asyncness = header.asyncness.print_with_space(); + let unsafety = header.unsafety.print_with_space(); + let defaultness = print_default_space(meth.is_default()); + let abi = print_abi_with_space(header.abi).to_string(); + // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. + let generics_len = format!("{:#}", g.print(cx.cache())).len(); + let mut header_len = "fn ".len() + + vis.len() + + constness.len() + + asyncness.len() + + unsafety.len() + + defaultness.len() + + abi.len() + + name.as_str().len() + + generics_len; + let (indent, end_newline) = if parent == ItemType::Trait { header_len += 4; (4, false) @@ -1028,17 +1035,18 @@ fn render_assoc_item( (0, true) }; render_attributes(w, meth, false); + w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len()); write!( w, "{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\ {generics}{decl}{spotlight}{where_clause}", if parent == ItemType::Trait { " " } else { "" }, - meth.visibility.print_with_space(cx.tcx(), meth.def_id, cx.cache()), - header.constness.print_with_space(), - header.asyncness.print_with_space(), - header.unsafety.print_with_space(), - print_default_space(meth.is_default()), - print_abi_with_space(header.abi), + vis, + constness, + asyncness, + unsafety, + defaultness, + abi, href = href, name = name, generics = g.print(cx.cache()), |
