blaise/stdlib
Graeme Geldenhuys 4c74506e0f perf(stdlib): hash index for unsorted TStringList.Find/IndexOf
Profiling the compiler self-compile (--emit-ir, callgrind) showed 86% of
all instructions inside linear scans of five unsorted TStringLists
(FUnitSymbols 68%, FMethodIndex 12%, FStrLits 4%, FUnitIfaces 2%);
TStringList.Find averaged 145 Compare calls per lookup, and each
iteration paid six ARC ops through Compare's by-value string params.

Unsorted lists with >= 16 entries now build a lazy open-addressing hash
index on first Find: FNV-1a over the bytes, case-folded when the list is
case-insensitive, kept at <= 50% load so an empty slot terminates every
probe.  Duplicate keys keep the first-added index, preserving the
IndexOf contract that overload registration relies on.  Appends update
the table in place; Delete/Insert/Put/Clear/CustomSort and the
Sorted/CaseSensitive setters invalidate it for lazy rebuild.  Sorted
lists keep using binary search; small lists keep the linear scan.

Compiler self-compile: 4.75 s -> 0.91 s wall (5.2x), 71.6G -> 10.5G
instructions (6.8x).  Behaviour contract pinned by 12 new in-process
tests in cp.test.stringlistfind.pas, written against the old linear
implementation first.
2026-06-10 18:54:37 +01:00
..
src/main/pascal perf(stdlib): hash index for unsorted TStringList.Find/IndexOf 2026-06-10 18:54:37 +01:00
project.xml refactor: split rtl/ into runtime/ + stdlib/, rename bcl.testing to blaise.testing 2026-05-16 00:51:18 +01:00