Skip to content

Add static methods for all operations, #54 - #59

Open
Hamad-canCode wants to merge 1 commit into
feature23:mainfrom
Hamad-canCode:static-method-conversion
Open

Add static methods for all operations, #54#59
Hamad-canCode wants to merge 1 commit into
feature23:mainfrom
Hamad-canCode:static-method-conversion

Conversation

@Hamad-canCode

Copy link
Copy Markdown

Fixes #54.

The library required instantiating an object to run any algorithm. Every type now
also exposes its operations as public static methods, so a one-off computation
needs no allocation:

var distance = Levenshtein.GetDistance("My string", "My $tring");
var similarity = JaroWinkler.GetSimilarity("My string", "My $tring", threshold: 0.9);

Instance methods delegate to the statics, passing their state as parameters, so
this is not a breaking change and implementations can still be swapped through the
interfaces.

Static API

┌────────────────────────┬────────────────────────────────────┐
│          Type          │           Static methods           │
├────────────────────────┼────────────────────────────────────┤
│                        │ GetSimilarity(s1, s2, k =          │
│ CosineDEFAULT_K), GetDistance(...),      │
│                        │ GetSimilarity(profile1, profile2)  │
├────────────────────────┼────────────────────────────────────┤
│ DamerauGetDistance(string/span)           │
├────────────────────────┼────────────────────────────────────┤
│ Jaccard                │ GetSimilarity/GetDistance(s1, s2,  │
│                        │ k = DEFAULT_K)                     │
├────────────────────────┼────────────────────────────────────┤
│                        │ GetSimilarity/GetDistance(string/s │
│ JaroWinkler            │ pan, threshold =                   │
│                        │ DEFAULT_THRESHOLD)                 │
├────────────────────────┼────────────────────────────────────┤
│ Levenshtein            │ GetDistance(string/span[, limit])  │
├────────────────────────┼────────────────────────────────────┤
│ LongestCommonSubsequen │ GetDistance(string/span),          │
│ ce                     │ GetLength(string/span)             │
├────────────────────────┼────────────────────────────────────┤
│ MetricLCS              │ GetDistance(string/span)           │
├────────────────────────┼────────────────────────────────────┤
│ NGram                  │ GetDistance(s0, s1, n = DEFAULT_N) │
├────────────────────────┼────────────────────────────────────┤
│ NormalizedLevenshtein  │ GetDistance/GetSimilarity(string/s │
│                        │ pan)                               │
├────────────────────────┼────────────────────────────────────┤
│ OptimalStringAlignment │ GetDistance(string/span)           │
├────────────────────────┼────────────────────────────────────┤
│                        │ GetDistance(s1, s2, k =            │
│ QGramDEFAULT_K), GetDistance(profile1,  │
│                        │ profile2)                          │
├────────────────────────┼────────────────────────────────────┤
│ RatcliffObershelp      │ GetSimilarity/GetDistance          │
├────────────────────────┼────────────────────────────────────┤
│ ShingleBased           │ GetProfile(s, k)                   │
├────────────────────────┼────────────────────────────────────┤
│ Sift4                  │ GetDistance(s1, s2, maxOffset =    │
│                        │ DEFAULT_MAX_OFFSET)                │
├────────────────────────┼────────────────────────────────────┤
│ SorensenDice           │ GetSimilarity/GetDistance(s1, s2,  │
│                        │ k = DEFAULT_K)                     │
├────────────────────────┼────────────────────────────────────┤
│                        │ GetDistance(s1, s2,                │
│ WeightedLevenshtein    │ characterSubstitution,             │
│                        │ characterInsDel = null, limit =    │
│                        │ double.MaxValue)                   │
└────────────────────────┴────────────────────────────────────┘

Supporting changes

  • ShingleBased.GetProfile split into an instance method (uses k) and a static
    GetProfile(s, k) carrying the same k <= 0 guard as the constructor.
  • DEFAULT_K, NGram.DEFAULT_N, and Sift4.DEFAULT_MAX_OFFSET are now public
    consts so they can serve as the statics' default arguments.
  • WeightedLevenshtein's InsertionCost/DeletionCost helpers take the
    ICharacterInsDel as a parameter; NormalizedLevenshtein dropped its
    Levenshtein field in favor of Levenshtein.GetDistance; the internal
    LongestCommonSubsequence.Length became the public GetLength.
  • No existing member changed signature or behavior — instance methods are pure
    delegation.

Benchmarks

Added a Static variant of each benchmark under #if STATIC_METHODS, with the
constant defined in the benchmarks csproj so it can be removed when benchmarking
against an older version of the library. Also added the missing instance Sift4
benchmark to give its static counterpart a baseline.

Tests

New StaticMethodsTest asserts static/instance parity for every algorithm,
including non-default state and the span overloads. Test count goes from 57 to 72,
passing on net8.0, net9.0, net10.0, and net481.

Every algorithm now exposes its operations as public static methods
(GetDistance/GetSimilarity/GetLength/GetProfile). Instance methods delegate
to them, passing any configured state (k, n, threshold, MaxOffset, character
weights) as parameters, so existing signatures and behavior are unchanged.
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.

Add static methods for all operations

1 participant