What's Changed
Performance:
- Rewrote the core lookup path with a reusable, generation-stamped scratch buffer instead of allocating/freeing a hash set on every call which cuts both dictionary load time and per-lookup overhead significantly.
- Average lookup time: ~30µs → ~3µs (~10x faster)
- Dictionary load time: ~1040ms → ~500ms (~2x faster)
- Benchmarked head-to-head against the reference C# SymSpell implementation on the same dataset: this C99 port now loads faster (~500ms vs ~820ms) and edges out the reference on lookup speed too (~3.2µs vs ~3.5µs average)
- Accuracy unchanged: 84.0% on the Wikipedia misspelling benchmark
Fixed:
- Empty and whitespace-only input no longer returns bogus suggestions (e.g. " " incorrectly matched short words like "of", "in", "to"). symspell_lookup() now correctly returns 0 for blank queries
⚠️ Breaking change:
- symspell_lookup() dropped its verbosity parameter (SYMSPELL_VERBOSITY_TOP/CLOSEST/ALL are gone). The function now always returns candidates at the closest edit distance, ordered and capped by max_suggestions. Update any calling code from:
symspell_lookup(dict, term, SYMSPELL_VERBOSITY_TOP, max_edit_distance, suggestions, max_suggestions) - to:
symspell_lookup(dict, term, max_edit_distance, suggestions, max_suggestions) - Note: building test_symspell for full sorted results requires -DDO_SORT (see Makefile); without it, lookup returns only the single best match, which is the fast path used for the benchmark numbers above.
Usage
make
./test_symspell dictionaries/dictionary.txtSee README.md for full documentation.
Credits
Special thanks to Dr. James Freeman for his insights.