我有一个List<byte[]>
并且我喜欢将每个反序列byte[]
化为 Foo。List 是有序的,我喜欢编写一个并行循环,其中结果List<Foo>
包含与原始 Foo 相同的顺序的所有 Foo byte[]
。该列表非常大,以使并行操作值得。有没有内置的方法来实现这一点?
如果没有,有什么想法可以通过同步运行来实现加速?
谢谢
我有一个List<byte[]>
并且我喜欢将每个反序列byte[]
化为 Foo。List 是有序的,我喜欢编写一个并行循环,其中结果List<Foo>
包含与原始 Foo 相同的顺序的所有 Foo byte[]
。该列表非常大,以使并行操作值得。有没有内置的方法来实现这一点?
如果没有,有什么想法可以通过同步运行来实现加速?
谢谢
根据您提供的信息,我知道您想要一个 Foo 的输出数组,其大小等于输入的字节数组?它是否正确?
如果是这样,是的,操作很简单。不要为锁定或同步结构而烦恼,这些会侵蚀并行化为您提供的所有速度。
相反,如果你遵守这个简单的规则,任何算法都可以在没有锁定或同步的情况下并行化:
对于每个处理的输入元素 X[i],您可以从任何输入元素 X[j] 中读取,但只能写入输出元素 Y[i]
查找 Scatter/Gather,这种类型的操作称为聚集,因为只有一个输出元素被写入。
如果您可以使用上述原则,那么您希望预先创建输出数组 Foo[],并在输入数组上使用 Parallel.For 而不是 ForEach。
例如
List<byte[]> inputArray = new List<byte[]>();
int[] outputArray = new int[inputArray.Count];
var waitHandle = new ManualResetEvent(false);
int counter = 0;
Parallel.For(0, inputArray.Count, index =>
{
// Pass index to for loop, do long running operation
// on input items
// writing to only a single output item
outputArray[index] = DoOperation(inputArray[index]);
if(Interlocked.Increment(ref counter) == inputArray.Count -1)
{
waitHandle.Set();
}
});
waitHandler.WaitOne();
// Optional conversion back to list if you wanted this
var outputList = outputArray.ToList();
您可以使用带有索引 int 键的线程安全字典来存储来自 foo 的结果,因此最后您将拥有字典中的所有数据排序器