我遇到了实现ContiguousChunkLazyEnumerator
类,它由PLINQ使用(使用此迭代器执行块的遍历)。 MoveNext
方法使用对源IEnumerator
的线程安全访问(通过使用speficied lock
),此外,它还保存了对内部缓冲区的访问结果。这是一段简短的代码:
lock (m_sourceSyncLock)
{
// Some .net stuff
try
{
for (; i < mutables.m_nextChunkMaxSize && m_source.MoveNext(); i++)
{
// Read the current entry into our buffer.
chunkBuffer[i] = m_source.Current;
}
}
// Some .net stuff
}
这样的迭代器将由工作线程使用(N个工作线程使用相同的迭代器)。但我真的不明白这种并行方法的好处。在此上下文中使用lock
应该可以消除任何性能优势。我的假设是,唯一的工作线程的等权访问应该以相同的速度工作。
答案 0 :(得分:3)
这是因为使用PLINQ可以优化项目的并发处理,而不是项目的并发枚举。
每个块完成繁重的lock
,因此多个线程将在块之间相互产生。
如果你有一个IEnumerable
可以快速枚举(例如List<T>
,那么这真的很闪耀,实际上,List<T>
有内部优化,所以不是最好的例子) ,并希望对结果进行一些缓慢的计算工作。
此代码用于创建分区数据,然后由多个线程使用。虽然它是线程安全的,但它不应该是最快的并发枚举。它针对数据局部性进行了优化。