UTF-8 coercion is slow
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 123
- Forks
- 20
- PR merge metrics
- No merged PRs in 30d
Description
When files are uploaded and chardet detects the encoding type "ascii", the raw bytes are passed to Unicode, Dammit in order to coerce them to UTF-8:
try:
# try to decode the string using the encoding we get
decoded_string = raw_bytes.decode(encoding_type)
except (UnicodeDecodeError, TypeError):
# try unicode dammit if chardet didn't work
dammit = UnicodeDammit(raw_bytes)
encoding_type = dammit.original_encoding
decoded_string = raw_bytes.decode(encoding_type)
For a novel, this can take 15-16 seconds. The explanation is in the BeautifulSoup documentation:
Unicode, Dammit guesses correctly most of the time, but sometimes it makes mistakes. Sometimes it guesses correctly, but only after a byte-by-byte search of the document that takes a very long time.
Instead, it might be a good idea to feed Unicode, Dammit some "best guesses" as to what the encoding is. Here is what that might look like (along with some slight streamlining of the code):
try:
# Try to decode the string using the encoding we get from chardet
decoded_string = raw_bytes.decode(encoding_type)
except (UnicodeDecodeError, TypeError):
# Try Unicode, Dammit if chardet didn't work, providing some best guesses if chardet detected "ascii"
if encoding_type == "ascii":
dammit = UnicodeDammit(raw_bytes, ["iso-8859-1", "iso-8859-15", "windows-1252"])
else:
dammit = UnicodeDammit(raw_bytes)
decoded_string = dammit.unicode_markup
For the same novel, this gets the job done in 2-3ms! The downside is that we potentially increase the chance that Unicode, Dammit will guess the wrong encoding, but it seems worth the payoff to me.
If we encounter similar bottlenecks with non-ASCII character sets, we could add similar "best guesses" for those.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lexos/helpers/general_functions.py at the linked encoding-coercion code and trace the upload path that passes detected encodings to Unicode, Dammit. Compare the ASCII case with the proposed best guesses using the same novel-sized input. Done means the ASCII path avoids the reported 15–16 second delay while still producing UTF-8 text.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, performance
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100