From 18e31fa578407abc1c42a47dfac2572cccfdf82e Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 10 Nov 2020 20:19:12 -0600 Subject: [PATCH] perf: Avoid hashing withut custom dict `HashMap::get` (at least hashbrown) hashes before getting and doesn't check if dict is empty. For the custom dict, a common use case will have the dict be empty. Master: ``` real 0m26.675s user 0m33.683s sys 0m4.535s ``` Bypassing `HashMap::get` ``` real 0m16.415s user 0m14.519s sys 0m4.118s ``` On a moderately sized repo. --- src/dict.rs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/dict.rs b/src/dict.rs index f3178e5..443a616 100644 --- a/src/dict.rs +++ b/src/dict.rs @@ -168,7 +168,7 @@ impl<'i, 'w, D: typos::Dictionary> Override<'i, 'w, D> { .collect(); } - pub fn interpret<'z, I: Iterator>( + fn interpret<'z, I: Iterator>( cases: I, ) -> impl Iterator)> { cases.map(|(typo, correction)| { @@ -186,19 +186,29 @@ impl<'i, 'w, D: typos::Dictionary> Override<'i, 'w, D> { impl<'i, 'w, D: typos::Dictionary> typos::Dictionary for Override<'i, 'w, D> { fn correct_ident<'s, 't>(&'s self, ident: typos::tokens::Identifier<'t>) -> Option> { - self.identifiers - .get(ident.token()) - .map(|c| c.borrow()) - .or_else(|| self.inner.correct_ident(ident)) + // Skip hashing if we can + if !self.identifiers.is_empty() { + self.identifiers + .get(ident.token()) + .map(|c| c.borrow()) + .or_else(|| self.inner.correct_ident(ident)) + } else { + None + } } fn correct_word<'s, 't>(&'s self, word: typos::tokens::Word<'t>) -> Option> { - let w = UniCase::new(word.token()); - // HACK: couldn't figure out the lifetime issue with replacing `cloned` with `borrow` - self.words - .get(&w) - .cloned() - .or_else(|| self.inner.correct_word(word)) + // Skip hashing if we can + if !self.words.is_empty() { + let w = UniCase::new(word.token()); + // HACK: couldn't figure out the lifetime issue with replacing `cloned` with `borrow` + self.words + .get(&w) + .cloned() + .or_else(|| self.inner.correct_word(word)) + } else { + None + } } }