Skip to content

Add an ASCII fast path for String#casecmp? - #17444

Merged
nobu merged 1 commit into
ruby:masterfrom
sampokuokkanen:casecmp-p-fastpath
Jun 23, 2026
Merged

Add an ASCII fast path for String#casecmp?#17444
nobu merged 1 commit into
ruby:masterfrom
sampokuokkanen:casecmp-p-fastpath

Conversation

@sampokuokkanen

@sampokuokkanen sampokuokkanen commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

String#casecmp? folds both operands with a Unicode case fold, allocating two new strings, and compares the results. For ASCII-only strings, Unicode case folding is equivalent to ASCII case-insensitive comparison, so the operands can be compared byte-by-byte without allocating anything.

#casecmp is older and does not take Unicode into account, which makes it faster. So this will add a fast path to #casecmp? so that the performance will be around the same. Turned off GC for that benchmark as it made the bench noisy (like in ruby/benchmark/string_concat.yml).

Benchmark

Apple M1 Pro (arm64-darwin)

case master this PR speedup
casecmp_p-1 (36 B) 3.12M 18.57M ~5.9x
casecmp_p-10 (360 B) 358k 3.00M ~8.4x
casecmp_p-100 (3.6 KB) 282k 357k ~1.3x
casecmp_p-1000 (36 KB) 25.4k 39.3k ~1.5x

Docker Linux (aarch64-linux)

case master this PR speedup
casecmp_p-1 (36 B) 5.03M 18.47M ~3.7x
casecmp_p-10 (360 B) 744k 2.73M ~3.7x
casecmp_p-100 (3.6 KB) 130k 379k ~2.9x
casecmp_p-1000 (36 KB) 12.1k 39.3k ~3.2x

AMD Ryzen 7 5700G (8C/16T) — Windows 11 (x64-mingw-ucrt, gcc 16.1.0, MSYS2 UCRT64)

case master this PR speedup
casecmp_p-1 (36 B) 6.38M 18.32M ~2.9x
casecmp_p-10 (360 B) 1.20M 3.18M ~2.7x
casecmp_p-100 (3.6 KB) 175k 348k ~2.0x
casecmp_p-1000 (36 KB) 15.97k 35.11k ~2.2x

Non-ASCII (fast path not taken) is unchanged:

case master this PR speedup
casecmp_p-nonascii1 1.221M 1.235M ~1.0x
casecmp_p-nonascii10 161.96k 159.39k ~1.0x
casecmp_p-nonascii100 16.86k 16.81k ~1.0x
casecmp_p-nonascii1000 1.749k 1.753k ~1.0x

String#casecmp? folds both operands with a Unicode case fold, allocating two new strings, and compares the results. For ASCII-only strings, Unicode case folding is equivalent to ASCII case-insensitive comparison, so the operands can be compared byte-by-byte without allocating anything.
@nobu
nobu merged commit 13fe77d into ruby:master Jun 23, 2026
123 checks passed
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.

2 participants