Skip to content

Migrate scoring APIs to double precision for v6.0.0 - #32

Merged
ycherkes merged 7 commits into
masterfrom
feat/v6-double-precision-scoring
Aug 21, 2026
Merged

ycherkes merged 7 commits into
masterfrom
feat/v6-double-precision-scoring

Conversation

@ycherkes

@ycherkes ycherkes commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #28

Summary

  • migrate scorer interfaces, cached scorers, scoring strategies, Fuzz methods, extraction results, and extraction cutoffs from int to double
  • preserve fractional similarity values throughout standard, cached, parallel, and pipeline extraction paths
  • remove scoreCutoff from the Indel, Levenshtein, longest-common-subsequence, and partial-ratio APIs
  • retain partial-ratio pruning as an internal implementation detail while removing cutoff behavior from the public scoring API
  • optimize character similarity and token-set scoring hot paths by specializing common-affix trimming, bulk-populating pattern-match vectors, and reducing temporary allocations
  • update tests, benchmarks, examples, and documentation for double-precision scores
  • bump package, assembly, and file versions to 6.0.0
  • replace the legacy branch-specific workflows with a single read-only workflow that builds, tests, packs, and uploads .nupkg and .snupkg files as GitHub Actions artifacts only

Breaking changes

  • scorer and strategy return types are now double
  • Fuzz methods now return fractional double scores instead of rounded integers
  • ExtractedResult<T>.Score, scorer delegates, and extraction cutoff parameters now use double
  • scoreCutoff parameters have been removed from the distance and partial-ratio APIs
  • custom implementations of IRatioScorer, ICachedRatioScorer, and their generic variants must update their Score return types to double

Validation

  • built the complete solution in Release configuration on all configured target frameworks
  • passed 5,126 tests on each of netframework4.6.2, netframework4.7.2, net8.0, and net10.0 (20,504 total test executions)
  • built the benchmark project successfully
  • reduced the extended construction-inclusive static Levenshtein benchmark from 153.0 ns to 123.4 ns (19.3%) and allocation from 144 B to 80 B; cached matching improved from 77.2 ns to 73.3 ns (5.0%)
  • generated Raffinert.FuzzySharp.6.0.0.nupkg and Raffinert.FuzzySharp.6.0.0.snupkg
  • verified the workflow contains no NuGet registry push, package-write permission, or publishing credentials

  - add bulk character population and ASCII fast paths
  - lazily allocate non-ASCII storage
  - rename benchmark labels to Raffinert.FuzzySharp
  - update v6 migration documentation and PR summary
@ycherkes
ycherkes merged commit b30758b into master Aug 21, 2026
2 checks passed
@ycherkes
ycherkes deleted the feat/v6-double-precision-scoring branch August 21, 2026 13:18
ancgate pushed a commit to ancgate/Fuzzion that referenced this pull request Nov 4, 2026
…token sort order

Plan items Raffinert#31 and Raffinert#32 (Phase 7).

- StringPreprocessor.RemoveDiacritics (NFD, drop combining marks, NFC,
  plus ß/æ/œ/ø/ł/đ/þ spelled out) and StringPreprocessor.Compose.
- StringPreprocessor.FullUnicode, matching RapidFuzz's default_process:
  Python's isalnum (keeps ², ½, Ⅻ), simple lowercase mapping (İ -> i,
  which .NET's invariant casing leaves unchanged), whole characters
  outside the BMP. Full is unchanged.
- CodePoints.Compare(a, b, metric) / CodePoints.Scorer(scorer): compare
  by code point with any metric or scorer, by replacing each distinct
  character outside the BMP with an unused private-use character, in code
  point order. Chosen over a TextUnit enum overload, which would make
  Fuzz.Ratio(a, b, 0) ambiguous.

Fix: token scorers sorted words with the current culture instead of
ordinally (Python sorts by code point), so mixed-case or accented words
scored differently from RapidFuzz and results could depend on the
machine's culture. TokenSortRatio("Zoo apple", "apple zoo") was 88.9,
now 55.6 as in RapidFuzz. Inherited from Raffinert.FuzzySharp; found
because code-point token scores disagreed with the oracle.

Oracle: new unicode-cases.json with 300 emoji/CJK Extension B/Deseret
pairs (7 metrics via CodePoints), 300 default_process strings and 200
mixed-case sentence pairs for the token scorers. All match. The two
token-sort tests fail when the old culture-sensitive sort is restored.

All 5,628 tests pass on net8.0 and net10.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016t3BEHkMD2QGVHNJcT4FuL
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.

return double from Process.Extract*

1 participant