From d6e847123902c655ff667c7db5511975f65cb8f8 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Tue, 20 Jul 2021 17:15:10 +0100 Subject: [PATCH] Lazily enumerate source enumerable Don't consume with ToArray() before iterating and yielding results back. This decreases allocations --- .../EnumerableExtensions.cs | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/X10D/src/EnumerableExtensions/EnumerableExtensions.cs b/X10D/src/EnumerableExtensions/EnumerableExtensions.cs index d6ca9f6..b0a2b244 100644 --- a/X10D/src/EnumerableExtensions/EnumerableExtensions.cs +++ b/X10D/src/EnumerableExtensions/EnumerableExtensions.cs @@ -1,6 +1,5 @@ -using System; +using System; using System.Collections.Generic; -using System.Linq; namespace X10D { @@ -23,24 +22,38 @@ namespace X10D } /// - /// Splits into chunks of size . + /// Splits into chunks of size . /// /// Any type. - /// The collection to split. + /// The collection to split. /// The maximum length of the nested collection. /// /// An containing an of /// whose lengths are no greater than . /// - public static IEnumerable> Split(this IEnumerable value, int chunkSize) + public static IEnumerable> Split(this IEnumerable source, int chunkSize) { - var enumerable = value.ToArray(); - var count = enumerable.LongLength; - chunkSize = chunkSize.Clamp(1, enumerable.Length); - - for (var i = 0; i < (int)(count / chunkSize); i++) + if (source is null) { - yield return enumerable.Skip(i * chunkSize).Take(chunkSize); + throw new ArgumentNullException(nameof(source)); + } + + var buffer = new List(chunkSize); + + foreach (var item in source) + { + buffer.Add(item); + + if (buffer.Count >= chunkSize) + { + yield return buffer; + buffer.Clear(); + } + } + + if (buffer.Count > 0) + { + yield return buffer; } } }