Split a List into Sublists of Size N

How do you write a code in C# to split the list [a, b, c, d, e, f, g, h] into sublists [a, b, c], [d, e, f], [g, h] each with three elements and the last with less than three? The most popular answer is the following LINQ.

In StackOverflow, this LINQ got more than 900 upvotes as of the answer to two questions (Split a List into smaller lists of N size [duplicate], Split List into Sublists with LINQ).

However, this method has the worst performance in any assumed answers. It creates the same number of objects with Index and Value as the length of the source. Object creation is a costly operation in terms of both memory and speed. Although the cost is much smaller, the exact count of divisions and comparisons as the length of the source is also not good for performance.

If you need performance, you should not use LINQ in the first place, but if you insist on a concise LINQ, how about the following solution.

The following are the benchmark results taken from BenchmarkDotNet, which splits a 1000-length array of ints into three pieces each. The first answer is Splitter1, and the above is Splitter2. Mean is the average, and the rests are measurement errors. The results show Splitter2 was more than 3.5 times faster than Splitter1.

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1766 (21H2)
AMD Ryzen 7 3800X, 1 CPU, 16 logical and 8 physical cores
.NET SDK=6.0.106
  [Host]  : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT
  LongRun : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT

Job=LongRun  IterationCount=100  LaunchCount=3  
WarmupCount=15  
MethodMeanErrorStdDev
Splitter189.94 μs0.351 μs1.779 μs
Splitter224.04 μs0.100 μs0.517 μs

If the target framework of your projects is .NET 6 or later, you should use the Chunk method for this operation, which is introduced in .NET 6. The benchmark results, including the Chunk method, are shown below. It was more than 4,000 times faster than Splitter2.

MethodMeanErrorStdDev
Splitter188,650.102 ns245.2557 ns1,251.8625 ns
Splitter223,481.503 ns117.8934 ns600.6975 ns
Chunk5.609 ns0.0198 ns0.0984 ns

Leave a Reply

Your email address will not be published. Required fields are marked *