Skip to content

Modernization: Span/ReadOnlyMemory support and remove ToCharArray allocations in StringSimilarity #26

Description

@lassevk

The library is entirely IList<T>-based and does no span work. A few concrete opportunities:

1. StringSimilarityDiffElementAligner.StringSimilarity allocates two char[] per comparison (src/DiffLib/Alignment/StringSimilarityDiffElementAligner.cs:46-49):

char[] element1Array = element1.ToCharArray();
char[] element2Array = element2.ToCharArray();
DiffSection[]? diffSections = Diff.CalculateSections(element1Array, element2Array, new DiffOptions()).ToArray();

This runs for every candidate pair inside the similarity aligner, so it can allocate a lot. A ReadOnlySpan<char> / ReadOnlyMemory<char> code path (or even a cheap IList<char>-over-string wrapper) would remove both the ToCharArray copies and the .ToArray() on the sections.

2. Public span-based entry point. A ReadOnlySpan<T> overload of CalculateSections would let callers diff strings, arrays and stack buffers without allocating. Caveat worth capturing in the design: the current API returns a lazy IEnumerable<DiffSection> built with yield, and ref struct spans can't be captured by iterators/closures. A span overload would need an eager (array/list-returning) implementation, or an internal refactor separating the algorithm from the yield wrapper.

3. LongestCommonSubsequence hashing currently boxes/looks up per element through IEqualityComparer. For the common char/primitive cases a span + EqualityComparer<T>.Default fast path could help, but only worth it after (2).

Suggest scoping this as: first extract the core algorithm behind an index-based read-only seam (see the IReadOnlyList<T> issue), then add span overloads on top.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions