From 74147b86c50ebdaa7d8420fcbf82fa647a6db394 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 21 Aug 2021 16:58:29 -0700 Subject: [PATCH] Use the length limit as the initial capacity The length limit turns out to be a surprisingly good heuristic for initial allocation size. See here for more details [1]. [1]: https://github.com/rust-lang/rust/pull/88173#discussion_r692531631 --- src/librustdoc/html/length_limit.rs | 12 +++++++++++- src/librustdoc/html/markdown.rs | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/length_limit.rs b/src/librustdoc/html/length_limit.rs index 91e098979acf..cc4a7f37fe9a 100644 --- a/src/librustdoc/html/length_limit.rs +++ b/src/librustdoc/html/length_limit.rs @@ -29,8 +29,18 @@ pub(super) struct HtmlWithLimit { impl HtmlWithLimit { /// Create a new buffer, with a limit of `length_limit`. pub(super) fn new(length_limit: usize) -> Self { + let buf = if length_limit > 1000 { + // If the length limit is really large, don't preallocate tons of memory. + String::new() + } else { + // The length limit is actually a good heuristic for initial allocation size. + // Measurements showed that using it as the initial capacity ended up using less memory + // than `String::new`. + // See https://github.com/rust-lang/rust/pull/88173#discussion_r692531631 for more. + String::with_capacity(length_limit) + }; Self { - buf: String::new(), + buf, len: 0, limit: length_limit, unclosed_tags: Vec::new(), diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5a569c690e54..b2ca13499818 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1096,7 +1096,6 @@ fn markdown_summary_with_limit( let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer)); let mut p = LinkReplacer::new(p, link_names); - // FIXME: capacity let mut buf = HtmlWithLimit::new(length_limit); let mut stopped_early = false; p.try_for_each(|event| {