refactor: get rid of some allocations from WordSet - #4087
Conversation
|
Took a look, since you asked. I think there is one inconsistency worth fixing before this lands.
word.chars().map(|c| c.normalized().to_ascii_lowercase()).collect()but the dedup check and lookup go through Probe on your branch at let mut set = WordSet::default();
set.add("They're");
set.add("They\u{2019}re"); // same word, typographic apostropheThe duplicate is only a small waste, since Making the lenient comparisons normalize as well as case-fold would line both paths up, and would also let .all(|(a, b)| a.normalized().eq_ignore_ascii_case(&b.normalized()));Worth noting |
Yeah this PR wasn't meant to tackle the apostrophe problem/bug directly, just to improve the underlying
It sounds like you have identified the right way to fix the apostrophe bug. The contract in the
Are you sure? I only moved the calls to For the case matching part, yeah that was the reason I moved the normalized-to-lowercase into the inner collection. When one side is guaranteed to be lowercase we can use the slightly more efficient |
|
Yep, you're right about that one, and my fault for hanging the note off the wrong quote. The I checked it against both commits to be sure. Same probe on the base and on your head: The flip on the second line comes from two things stacking: While I was in there I found something that makes the normalize-the-lenient-comparisons fix look more attractive. Adding both apostrophe spellings stores the same word twice: On the base the two entries were at least different strings. On the head they're byte-identical, because One thing on the last point: I don't think Agreed on all the rest. Updating the |
Issues
Inspired by the discussion at #3202 but I don't think there's an issue this fixes per se.
Description
WordSethad places it calledcollect(), which resulted in allocations.I got rid of all the unnecessary ones by using methods on iterators instead.
This involved adding "lenient" versions of
eq_ch()andeq_str()that do allow the right-hand side to not already be lowercase. Instead, the words in theWordSetare now guaranteed to be lowercase so that they can be on the right-hand side of comparisons against&[char]and avoid allocations and conversions.Previously every word was allocated just to check if it was already in the
WordSet. This is now avoided.All tests pass but I would appreciate another pair of eyes well-versed in Harper's workings to make sure I didn't overlook anything as it's well past midnight.
How Has This Been Tested?
cargo testAI Disclosure
I'm pretty sure I rewrote by hand every single bit of code an AI came up with as it didn't always do what I wanted even though it did give me ideas of how to proceed.
Checklist