Repository navigation
Conversation
_Accumulator.__len__() summed the lengths of all the parts of the current line on every call, and it is called after every appended word, so folding a header whose line grows long took O(N**2) time. This is the case for Message.as_string(), which does not fold headers by default. Keep the total length up to date instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
email.header._Accumulator.__len__()added up the lengths of all the parts of the current line on every call, and_ValueFormatter._append_chunk()calls it after every word. When a line grows long, folding becomes O(N²). That is what happens by default inMessage.as_string(), which does not fold headers (maxheaderlen=0,compat32policy).The fix keeps the total length up to date in
push(),pop(),pop_from()andreset(), the only methods that change the accumulator, and__len__()returns it. Nothing else touches the list.Message.as_string()with one longSubject:header:Ordinary messages also get faster. For a message with a 20-address
To:header,as_string()goes from 100 µs to 38 µs andas_bytes()(folded at 78) from 68 µs to 52 µs.Testing:
New tests check that a long header is left unfolded with
maxlinelen=0and byMessage.as_string(), and thatlen()of the accumulator is correct after each kind of change.I compared the old and new code on 60,000 random
Header.encode()calls and on 15,000 random messages throughas_string()andas_bytes(). The calls varied:maxlinelen,splitchars,continuation_wsandlinesepThe output was identical.
test_email,test_mailbox,test_smtpliband the full test suite pass.AI disclosure: prepared with the help of Claude Code; I reviewed the change and the test results.