gpt4 book ai didi

c# - 使用 C# 将集合拆分为并行的相等批处理

转载 作者:太空宇宙 更新时间:2023-11-03 22:37:35 25 4
gpt4 key购买 nike

我正在尝试将集合拆分为相同数量的批处理。下面是代码。

   public static List<List<T>> SplitIntoBatches<T>(List<T> collection, int size)
{
var chunks = new List<List<T>>();
var count = 0;
var temp = new List<T>();

foreach (var element in collection)
{
if (count++ == size)
{
chunks.Add(temp);
temp = new List<T>();
count = 1;
}
temp.Add(element);
}

chunks.Add(temp);

return chunks;
}

我们是否可以使用 Parallel.ForEach() 来实现更好的性能,因为列表中有大约 100 万个项目?

谢谢!

最佳答案

如果关注性能,我的想法(按影响的递增顺序):

  • 在创建列表时调整列表的大小会节省很多的工作,即在开始复制之前计算出输出批量大小,即temp = new List<T>(thisChunkSize)
  • 使用数组比使用列表更有效 - new T[thisChunkSize]
  • 特别是如果你使用 BlockCopy (或 CopyTo ,在内部使用它)而不是一个一个地复制单个元素
  • 一旦计算出每个 block 的偏移量,就可以并行执行各个 block 副本,但我不认为它会更快 - 内存带宽将成为此时的限制因素
  • 最终解决方法是:根本不复制数据,而只是在现有数据上创建范围;例如,如果使用数组,ArraySegment<T>有助于;如果您愿意使用更新的 .NET 功能,那么这非常适合 Memory<T>/Span<T> - 在现有数组上创建内存/跨度范围基本上是免费且即时的 - 即采用 T[]并返回 List<Memory<T>>或类似的。

即使你不能切换到ArraySegment<T>/Memory<T>等,返回仍然可以使用的类似的东西 - 即 List<ListSegment<T>>其中 ListSegment<T>是这样的:

readonly struct ListSegment<T> { // like ArraySegment<T>, but for List<T>
public List<T> List {get;}
public int Offset {get;}
public int Count {get;}
}

并让您的代码与 ListSegment<T> 一起工作通过处理 OffsetCount适本地。

关于c# - 使用 C# 将集合拆分为并行的相等批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54214030/

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