BurntSushi / BurntSushi/bstr

ByteSlice::trim on ASCII whitespace is substantially slower than core::str::trim

Open
#89 3 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
1.1k
Forks
77
PR merge metrics
No merged PRs in 30d

Description

`ByteSlice::trim` (and related) are not competitive with libstd's in the case that the whitespace is ASCII.

The difference is as much as 50%, and is something I noticed when moving some code to use bstr, as a dip in that code's benchmarks.

I'm not an expert, but my understanding is that ASCII whitespace is much more common than non-ASCII whitespace in pretty much all scripts, so it's probably a good idea to optimize for.

---

Here are two benchmarks that demonstrate the issue: https://gist.github.com/thomcc/d017dec2bf7fbfd017e4f34cfd4db6f8 — it's a gist as it's a bit too long to really be great as a code block. It also contains a diff you can apply to insert them directly into bstrs existing benchmark code (2nd file in the gist).

The first (`trim/source-lines`) measures the time to trim a bunch of lines of source code (specifically, every line in `ext_slice.rs` — chosen arbitrarily), and is close to my real use case where, I saw an issues using bstr.

The second (`trim/large-ascii-padded`) is completely artificial, and just trims a huge string starting and ending with tons of ascii whitespace (with only a single non-whitespace character between it all to ensure both trim_start and trim_end are measured). It's focused on the specific issue, so probably better as a benchmark, but it doesn't reflect a real use case.

The results here show that for the current benchmark (`trim/tiny`), std and bstr are roughly the same performance, but that std is substantially faster on the the new benchmarks

```
bstr/trim/tiny time: [50.634 ns 50.925 ns 51.261 ns]
thrpt: [502.31 MiB/s 505.63 MiB/s 508.54 MiB/s]
std/trim/tiny time: [50.592 ns 50.743 ns 50.917 ns]
thrpt: [505.71 MiB/s 507.45 MiB/s 508.96 MiB/s]

bstr/trim/source-lines time: [90.672 us 90.931 us 91.222 us]
thrpt: [1.1964 GiB/s 1.2003 GiB/s 1.2037 GiB/s]
std/trim/source-lines time: [55.251 us 55.669 us 56.236 us]
thrpt: [1.9408 GiB/s 1.9605 GiB/s 1.9754 GiB/s]

bstr/trim/large-ascii-padded
time: [9.4068 us 9.4174 us 9.4304 us]
thrpt: [414.32 MiB/s 414.89 MiB/s 415.36 MiB/s]
std/trim/large-ascii-padded
time: [4.1390 us 4.1472 us 4.1559 us]
thrpt: [940.15 MiB/s 942.12 MiB/s 943.99 MiB/s]
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with ByteSlice::trim and related methods, then review the existing trim benchmarks and the benchmark additions in the linked gist. Use the ext_slice.rs source-lines case and the large-ascii-padded case to measure the current gap. Done means the ASCII-whitespace benchmarks show improved performance relative to std::str::trim.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.