From f8d2052c0a2cf2fab7892811dfb25c1263a49829 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 12 Jul 2024 20:38:08 +1000 Subject: [PATCH 1/2] move to IReadOnlyList avoid the array copy allocation of .ToArray() --- DiffPlex/Chunkers/CharacterChunker.cs | 6 ++++-- DiffPlex/Chunkers/CustomFunctionChunker.cs | 7 ++++--- DiffPlex/Chunkers/DelimiterChunker.cs | 4 ++-- DiffPlex/Chunkers/LineChunker.cs | 3 ++- DiffPlex/Chunkers/LineEndingsPreservingChunker.cs | 4 ++-- DiffPlex/DiffBuilder/InlineDiffBuilder.cs | 2 +- DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs | 2 +- DiffPlex/DiffPlex.csproj | 2 +- DiffPlex/Differ.cs | 6 +++--- DiffPlex/IChunker.cs | 6 ++++-- DiffPlex/Model/DiffResult.cs | 6 +++--- DiffPlex/Model/ModificationData.cs | 6 ++++-- .../Chunkers/LineEndingsPreservingChunkerFacts.cs | 8 ++++---- 13 files changed, 35 insertions(+), 27 deletions(-) diff --git a/DiffPlex/Chunkers/CharacterChunker.cs b/DiffPlex/Chunkers/CharacterChunker.cs index 85cd3dea..8076c4fe 100644 --- a/DiffPlex/Chunkers/CharacterChunker.cs +++ b/DiffPlex/Chunkers/CharacterChunker.cs @@ -1,4 +1,6 @@ -namespace DiffPlex.Chunkers +using System.Collections.Generic; + +namespace DiffPlex.Chunkers { public class CharacterChunker:IChunker { @@ -7,7 +9,7 @@ public class CharacterChunker:IChunker /// public static CharacterChunker Instance { get; } = new CharacterChunker(); - public string[] Chunk(string text) + public IReadOnlyList Chunk(string text) { var s = new string[text.Length]; for (int i = 0; i < text.Length; i++) s[i] = text[i].ToString(); diff --git a/DiffPlex/Chunkers/CustomFunctionChunker.cs b/DiffPlex/Chunkers/CustomFunctionChunker.cs index 43c57306..ac63c730 100644 --- a/DiffPlex/Chunkers/CustomFunctionChunker.cs +++ b/DiffPlex/Chunkers/CustomFunctionChunker.cs @@ -1,18 +1,19 @@ using System; +using System.Collections.Generic; namespace DiffPlex.Chunkers { public class CustomFunctionChunker: IChunker { - private readonly Func customChunkerFunc; + private readonly Func> customChunkerFunc; - public CustomFunctionChunker(Func customChunkerFunc) + public CustomFunctionChunker(Func> customChunkerFunc) { if (customChunkerFunc == null) throw new ArgumentNullException(nameof(customChunkerFunc)); this.customChunkerFunc = customChunkerFunc; } - public string[] Chunk(string text) + public IReadOnlyList Chunk(string text) { return customChunkerFunc(text); } diff --git a/DiffPlex/Chunkers/DelimiterChunker.cs b/DiffPlex/Chunkers/DelimiterChunker.cs index 0ec06a4f..cdb3ebb0 100644 --- a/DiffPlex/Chunkers/DelimiterChunker.cs +++ b/DiffPlex/Chunkers/DelimiterChunker.cs @@ -17,7 +17,7 @@ public DelimiterChunker(char[] delimiters) this.delimiters = delimiters; } - public string[] Chunk(string str) + public IReadOnlyList Chunk(string str) { var list = new List(); int begin = 0; @@ -76,7 +76,7 @@ public string[] Chunk(string str) } } - return list.ToArray(); + return list; } } } \ No newline at end of file diff --git a/DiffPlex/Chunkers/LineChunker.cs b/DiffPlex/Chunkers/LineChunker.cs index 7a5cda21..79c6b6ed 100644 --- a/DiffPlex/Chunkers/LineChunker.cs +++ b/DiffPlex/Chunkers/LineChunker.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace DiffPlex.Chunkers { @@ -11,7 +12,7 @@ public class LineChunker:IChunker /// public static LineChunker Instance { get; } = new LineChunker(); - public string[] Chunk(string text) + public IReadOnlyList Chunk(string text) { return text.Split(lineSeparators, StringSplitOptions.None); } diff --git a/DiffPlex/Chunkers/LineEndingsPreservingChunker.cs b/DiffPlex/Chunkers/LineEndingsPreservingChunker.cs index a58800a7..a3f8b9b8 100644 --- a/DiffPlex/Chunkers/LineEndingsPreservingChunker.cs +++ b/DiffPlex/Chunkers/LineEndingsPreservingChunker.cs @@ -11,7 +11,7 @@ public class LineEndingsPreservingChunker:IChunker /// public static LineEndingsPreservingChunker Instance { get; } = new LineEndingsPreservingChunker(); - public string[] Chunk(string text) + public IReadOnlyList Chunk(string text) { if (string.IsNullOrEmpty(text)) return emptyArray; @@ -45,7 +45,7 @@ public string[] Chunk(string text) output.Add(str); } - return output.ToArray(); + return output; } } } \ No newline at end of file diff --git a/DiffPlex/DiffBuilder/InlineDiffBuilder.cs b/DiffPlex/DiffBuilder/InlineDiffBuilder.cs index 2e82d2c5..730341c5 100644 --- a/DiffPlex/DiffBuilder/InlineDiffBuilder.cs +++ b/DiffPlex/DiffBuilder/InlineDiffBuilder.cs @@ -112,7 +112,7 @@ private static void BuildDiffPieces(DiffResult diffResult, List piece } } - for (; bPos < diffResult.PiecesNew.Length; bPos++) + for (; bPos < diffResult.PiecesNew.Count; bPos++) pieces.Add(new DiffPiece(diffResult.PiecesNew[bPos], ChangeType.Unchanged, bPos + 1)); } } diff --git a/DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs b/DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs index 3b5b122e..4441e0d2 100644 --- a/DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs +++ b/DiffPlex/DiffBuilder/SideBySideDiffBuilder.cs @@ -180,7 +180,7 @@ private static ChangeType BuildDiffPieces(DiffResult diffResult, List } } - while (bPos < diffResult.PiecesNew.Length && aPos < diffResult.PiecesOld.Length) + while (bPos < diffResult.PiecesNew.Count && aPos < diffResult.PiecesOld.Count) { oldPieces.Add(new DiffPiece(diffResult.PiecesOld[aPos], ChangeType.Unchanged, aPos + 1)); newPieces.Add(new DiffPiece(diffResult.PiecesNew[bPos], ChangeType.Unchanged, bPos + 1)); diff --git a/DiffPlex/DiffPlex.csproj b/DiffPlex/DiffPlex.csproj index acf73770..0bcbf10e 100644 --- a/DiffPlex/DiffPlex.csproj +++ b/DiffPlex/DiffPlex.csproj @@ -1,7 +1,7 @@  - net35;net40;netstandard1.0;netstandard2.0;net6.0 + net45;netstandard1.0;netstandard2.0;net6.0 1.7.2 diff DiffPlex is a diffing library that allows you to programmatically create text diffs. DiffPlex is a fast and tested library. diff --git a/DiffPlex/Differ.cs b/DiffPlex/Differ.cs index 585127d4..034108d7 100644 --- a/DiffPlex/Differ.cs +++ b/DiffPlex/Differ.cs @@ -333,10 +333,10 @@ private static void BuildPieceHashes(IDictionary pieceHash, Modific : chunker.Chunk(data.RawData); data.Pieces = pieces; - data.HashedPieces = new int[pieces.Length]; - data.Modifications = new bool[pieces.Length]; + data.HashedPieces = new int[pieces.Count]; + data.Modifications = new bool[pieces.Count]; - for (int i = 0; i < pieces.Length; i++) + for (int i = 0; i < pieces.Count; i++) { string piece = pieces[i]; if (ignoreWhitespace) piece = piece.Trim(); diff --git a/DiffPlex/IChunker.cs b/DiffPlex/IChunker.cs index bb977d8e..9e9de1a2 100644 --- a/DiffPlex/IChunker.cs +++ b/DiffPlex/IChunker.cs @@ -1,4 +1,6 @@ -namespace DiffPlex +using System.Collections.Generic; + +namespace DiffPlex { /// /// Responsible for how to turn the document into pieces @@ -8,6 +10,6 @@ public interface IChunker /// /// Divide text into sub-parts /// - string[] Chunk(string text); + IReadOnlyList Chunk(string text); } } \ No newline at end of file diff --git a/DiffPlex/Model/DiffResult.cs b/DiffPlex/Model/DiffResult.cs index 98a8b7c0..8055eb1e 100644 --- a/DiffPlex/Model/DiffResult.cs +++ b/DiffPlex/Model/DiffResult.cs @@ -10,12 +10,12 @@ public class DiffResult /// /// The chunked pieces of the old text /// - public string[] PiecesOld { get; } + public IReadOnlyList PiecesOld { get; } /// /// The chunked pieces of the new text /// - public string[] PiecesNew { get; } + public IReadOnlyList PiecesNew { get; } /// @@ -23,7 +23,7 @@ public class DiffResult /// public IList DiffBlocks { get; } - public DiffResult(string[] piecesOld, string[] piecesNew, IList blocks) + public DiffResult(IReadOnlyList piecesOld, IReadOnlyList piecesNew, IList blocks) { PiecesOld = piecesOld; PiecesNew = piecesNew; diff --git a/DiffPlex/Model/ModificationData.cs b/DiffPlex/Model/ModificationData.cs index b5271fad..9a6e0774 100644 --- a/DiffPlex/Model/ModificationData.cs +++ b/DiffPlex/Model/ModificationData.cs @@ -1,4 +1,6 @@ -namespace DiffPlex.Model +using System.Collections.Generic; + +namespace DiffPlex.Model { public class ModificationData { @@ -8,7 +10,7 @@ public class ModificationData public bool[] Modifications { get; set; } - public string[] Pieces { get; set; } + public IReadOnlyList Pieces { get; set; } public ModificationData(string str) { diff --git a/Facts.DiffPlex/Chunkers/LineEndingsPreservingChunkerFacts.cs b/Facts.DiffPlex/Chunkers/LineEndingsPreservingChunkerFacts.cs index 92434411..353afb55 100644 --- a/Facts.DiffPlex/Chunkers/LineEndingsPreservingChunkerFacts.cs +++ b/Facts.DiffPlex/Chunkers/LineEndingsPreservingChunkerFacts.cs @@ -16,7 +16,7 @@ public void should_split_lines_when_first_line_empty() var chunks = chunker.Chunk(sampleText); //ASSERT - Assert.Equal(4, chunks.Length); + Assert.Equal(4, chunks.Count); Assert.Equal("\r\n", chunks[0]); Assert.Equal("First\r\n", chunks[1]); Assert.Equal("Second\r\n", chunks[2]); @@ -34,7 +34,7 @@ public void should_split_lines_when_last_does_not_end_with_lineending() var chunks = chunker.Chunk(sampleText); //ASSERT - Assert.Equal(3, chunks.Length); + Assert.Equal(3, chunks.Count); Assert.Equal("First\r\n", chunks[0]); Assert.Equal("Second\r\n", chunks[1]); Assert.Equal("Last", chunks[2]); @@ -51,7 +51,7 @@ public void should_split_when_all_lines_are_empty() var chunks = chunker.Chunk(sampleText); //ASSERT - Assert.Equal(3, chunks.Length); + Assert.Equal(3, chunks.Count); Assert.Equal("\r\n", chunks[0]); Assert.Equal("\r\n", chunks[1]); Assert.Equal("\r\n", chunks[2]); @@ -68,7 +68,7 @@ public void should_split_when_different_line_ending() var chunks = chunker.Chunk(sampleText); //ASSERT - Assert.Equal(4, chunks.Length); + Assert.Equal(4, chunks.Count); Assert.Equal("\r\n", chunks[0]); Assert.Equal("First\n", chunks[1]); Assert.Equal("Second\r", chunks[2]); From c2a26592995a802416e8737148e18e45021412de Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 12 Jul 2024 20:38:31 +1000 Subject: [PATCH 2/2] Update DiffPlex.csproj --- DiffPlex/DiffPlex.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/DiffPlex/DiffPlex.csproj b/DiffPlex/DiffPlex.csproj index 0bcbf10e..2c5bd5b0 100644 --- a/DiffPlex/DiffPlex.csproj +++ b/DiffPlex/DiffPlex.csproj @@ -9,8 +9,6 @@ README.md - -