gpt4 book ai didi

c# - 将数组拆分成 block - 有更快的方法吗?

转载 作者:行者123 更新时间:2023-11-30 20:16:54 24 4
gpt4 key购买 nike

我正在寻找将数组拆分为固定大小块的最快方法(当然,最后一个可以更小)。我查看了整个网站,没有找到任何性能方面的比较,所以我写了它们,结果如下:

Time in microseconds, mean/error/stddev

For int[] - 30.02 | 0.1002 | 0.0937

For IEnumerable<int> - 76.67 | 0.2146 | 0.1902

更新:下面的版本(在@Markus 的回答中)是 139.5 | 0.6702 | 0.5597

在 SO 上最流行和经常推荐的使用 LINQ 的方法 GroupByindex/chunkSize是不行的 - 267 微秒比上述任何一个实现都大得多。

有没有更快的拆分数组的方法?

附言这是 Array 的代码和 IEnumerable<T> :

    /// <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;
}
}

带有 BenchmarkDotNet 测试的 P.P.S 完整解决方案是 on GitHub .

最佳答案

不太确定这是如何叠加的 (ArraySegment),但请尝试一下。我避免使用迭代器,但不确定这是否真的是一个收获。

public static IEnumerable<T[]> AsChunks<T>(
this T[] source, int chunkMaxSize)
{
var chunks = source.Length / chunkMaxSize;
var leftOver = source.Length % chunkMaxSize;
var result = new List<T[]>(chunks + 1);
var offset = 0;

for (var i = 0; i < chunks; i++)
{
result.Add(new ArraySegment<T>(source,
offset,
chunkMaxSize).ToArray());
offset += chunkMaxSize;
}

if (leftOver > 0)
{
result.Add(new ArraySegment<T>(source,
offset,
leftOver).ToArray());
}

return result;
}

关于c# - 将数组拆分成 block - 有更快的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47683209/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com