我正在寻找将数组按固定大小(最后一个可以更小)拆分成块的最快方法。我在整个站点上搜索并没有发现任何性能比较,因此我自己写了一下,以下是结果:
时间单位为微秒, 均值/误差/标准偏差 对于int[] - 30.02 | 0.1002 | 0.0937 对于IEnumerable - 76.67 | 0.2146 | 0.1902
更新: 版本如下(@Markus'回答中),为139.5 | 0.6702 | 0.5597
SO上最流行的、经常建议使用LINQ的GroupBy与index/chunkSize的方法不可用 - 267微秒远大于前述实现之一。
有没有更快的方法来拆分数组?
P.S. 这是Array和IEnumerable的代码:
时间单位为微秒, 均值/误差/标准偏差 对于int[] - 30.02 | 0.1002 | 0.0937 对于IEnumerable - 76.67 | 0.2146 | 0.1902
更新: 版本如下(@Markus'回答中),为139.5 | 0.6702 | 0.5597
SO上最流行的、经常建议使用LINQ的GroupBy与index/chunkSize的方法不可用 - 267微秒远大于前述实现之一。
有没有更快的方法来拆分数组?
P.S. 这是Array和IEnumerable的代码:
/// <summary>
/// Splits <paramref name="source"/> into chunks of size not greater than <paramref name="chunkMaxSize"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">Array to be split</param>
/// <param name="chunkMaxSize">Max size of chunk</param>
/// <returns><see cref="IEnumerable{T}"/> of <see cref="Array"/> of <typeparam name="T"/></returns>
public static IEnumerable<T[]> AsChunks<T>(this T[] source, int chunkMaxSize)
{
var pos = 0;
var sourceLength = source.Length;
do
{
var len = Math.Min(pos + chunkMaxSize, sourceLength) - pos;
if (len == 0)
{
yield break;;
}
var arr = new T[len];
Array.Copy(source, pos, arr, 0, len);
pos += len;
yield return arr;
} while (pos < sourceLength);
}
/// <summary>
/// Splits <paramref name="source"/> into chunks of size not greater than <paramref name="chunkMaxSize"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"><see cref="IEnumerable{T}"/> to be split</param>
/// <param name="chunkMaxSize">Max size of chunk</param>
/// <returns><see cref="IEnumerable{T}"/> of <see cref="Array"/> of <typeparam name="T"/></returns>
public static IEnumerable<T[]> AsChunks<T>(this IEnumerable<T> source, int chunkMaxSize)
{
var arr = new T[chunkMaxSize];
var pos = 0;
foreach (var item in source)
{
arr[pos++] = item;
if (pos == chunkMaxSize)
{
yield return arr;
arr = new T[chunkMaxSize];
pos = 0;
}
}
if (pos > 0)
{
Array.Resize(ref arr, pos);
yield return arr;
}
}
P.P.S 完整的解决方案和BenchmarkDotNet测试在GitHub上。