Skip to content

Add Support for none UTF-8 texts & Performance improvements - #2637

Merged
AmmarAbouZor merged 11 commits into
esrlabs:masterfrom
AmmarAbouZor:support-none-utf8
Sep 9, 2026
Merged

AmmarAbouZor merged 11 commits into
esrlabs:masterfrom
AmmarAbouZor:support-none-utf8

Conversation

@AmmarAbouZor

Copy link
Copy Markdown
Contributor

This PR closed #1921

It adds support for string encoding other that UTF-8 and also improve parsing performance for text sources to up 1.35 x and for attachments heavy dlt files with about 1.20 x

It includes:

  • Parse all text files regardless and removing linking text files special case. This allowed us to parse all text inputs into UTF-8 making all operations possible on them. It provides better user experience as user shouldn't wait until file indexing is done to start working with the file.
  • Introduce UTF-16 encoding parser.
  • At the start of the session with text parser, the app will sniff the first load of bytes to determine the encoding and select the matching parser automatically. This behavior is also reserved in binary exports.
  • UTF-8 parser can parser input lossily, making working with old windows special formats also possible.
  • Improve performance for text based parsers as they will be used for text files in all cases and we need them to be as fast as possible.
  • Improve general performance for parsing by heap allocating attachments to avoid having parser output reserving much space as it's actually needs.

Here is a table for performance changes:

input master branch gain
text file, 1.5 GB 2276 ms 1682 ms 1.35x faster, −26 %
DLT attachments heavy 2447 ms 2073 ms 1.18x faster, −15 %

Remove not needed decoder on stream byte sources removing the unwritten
contract that each source of them must stop on line breaks.
This changes is sound after the previous changes on producer loop to
ensure that parsers can communicate their state and what they need.

The serial port is no longer split into halves: reading and writing both
go through `&mut self`, so the lock behind the split paid for
concurrency that can't happen.

Also fixes the intermittently flappy TCP reconnect tests, which drove
real sockets under paused time and asserted on attempt counts read from
a `watch` channel that keeps the latest value only.
Text files were linked as the session file, so consumers read the
original bytes while the display path decoded them lossily. They now go
through the producer and StringTokenizer like every other source, which
makes the session file valid UTF-8 by construction.

- Drop SessionFileOrigin, the linked flow in observe_file and the
  origin checks in observe.rs; the session file is always generated.
- Delete dead code uncovered by this: grabber::factory,
  TextFileSource::contains_text, file_tools::is_binary, and the
  UpdateSession/GetSessionFileOrigin state APIs.
Use spawn_blocking instead of block_in_place as the move cost is small
compared with forcing a multi threaded tokio runtime as hidden contract
* Add parser for text encoded with UTF-16 format.
* Determine which text parser to use by sniffing the first few bytes of
  the source.
* Sniffing respects SDE income messages.
* String encoding is respected in raw exports too.
* Add files for testing and snapshot tests.
Replace logs general collector with special collector for benchmarks
which will avoid allocation on message, instead it'll write them into a
sink and clear it out once full to avoid measuring none-related memory
allocations
+ Add validation for texts benches to ensure the provided text input
  matches the bench's parser
Attachment can take much more space compared with messages.
This is the case for string parsers where we gain up to 15% performance
improvements with this changes.

It was also tested with attachments-heavy DLT files without any
noticeable regressions there.
Scan the whole provided bytes slice once for line breaks instead of
implementing single parser which will repeated memchar setup for each
line.

Changes improved performance about 5%
Performance improvements for UTF-16 parser by:
* Use memchar to find line breaks instead of the normal linear search
  with no SIMD.
* Scan & Parse all available bytes at once by implementing Parser trait
  instead of SingleParser

Changes ended up with 12% performance gain
Pre-allocate the output string instead of collecting.
This small change improved performance by about 30%

+ Small code style refactoring
@AmmarAbouZor
AmmarAbouZor merged commit c6d1e20 into esrlabs:master Sep 9, 2026
1 check passed
@AmmarAbouZor
AmmarAbouZor deleted the support-none-utf8 branch September 9, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support other than UTF8 coding

1 participant