WheatonCS / WheatonCS/Lexos

UTF-8 coercion is slow

Open
#1,068 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.