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.
The library is entirely
IList<T>-based and does no span work. A few concrete opportunities:1.
StringSimilarityDiffElementAligner.StringSimilarityallocates twochar[]per comparison (src/DiffLib/Alignment/StringSimilarityDiffElementAligner.cs:46-49):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 cheapIList<char>-over-stringwrapper) would remove both theToCharArraycopies and the.ToArray()on the sections.2. Public span-based entry point. A
ReadOnlySpan<T>overload ofCalculateSectionswould let callers diff strings, arrays and stack buffers without allocating. Caveat worth capturing in the design: the current API returns a lazyIEnumerable<DiffSection>built withyield, andref structspans 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 theyieldwrapper.3.
LongestCommonSubsequencehashing currently boxes/looks up per element throughIEqualityComparer. For the commonchar/primitive cases a span +EqualityComparer<T>.Defaultfast 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.