Jod*_*ell 6 .net c# iteration parallel-processing .net-4.0
编辑其他选项和下面稍微扩展的问题.
考虑一个类体的这个人为的抽象例子.它演示了执行"for"迭代的四种不同方法.
private abstract class SomeClass
{
public void someAction();
}
void Examples()
{
List<SomeClass> someList = new List<SomeClass>();
//A. for
for (int i = 0; i < someList.Count(); i++)
{
someList[i].someAction();
}
//B. foreach
foreach (SomeClass o in someList)
{
o.someAction();
}
//C. foreach extension
someList.ForEach(o => o.someAction());
//D. plinq
someList.AsParallel().ForAll(o => o.someAction());
Run Code Online (Sandbox Code Playgroud)
编辑:从答案和研究中添加一些选项.
//E. ParallelEnumerable
ParallelEnumerable.Range(0, someList.Count - 1)
.ForAll(i => someList[i].someAction());
//F. ForEach Parallel Extension
Parallel.ForEach(someList, o => o.someAction());
//G. For Parallel Extension
Parallel.For(0, someList.Count - 1, i => someList[i].someAction())
}
Run Code Online (Sandbox Code Playgroud)
我的问题分为两部分.我错过了一些重要的选择吗?考虑可读性但主要是性能,哪个选项是最佳选择?
请说明的复杂性SomeClass执行,或Count的someList会影响这个选择.
编辑:有这么令人眼花缭乱的选项,我不希望我的代码被选择破坏.要在我的问题中添加第三部分,如果我的列表可以是任何长度,我应该默认为并行选项吗?
作为一个稻草人.我怀疑,考虑到多处理器架构的普遍性,在所有选项SomeClass和所有长度的someList选项中//E. ParallelEnumerable都能提供最佳的平均性能.我没有做任何测试来证明这一点.
注意:并行扩展将需要使用System.Threading.Tasks命名空间.
选项A仅对实现索引的序列有意义,并且只对具有O(1)查找时间的序列执行.通常,我会使用foreach和变体,除非你有特殊的逻辑.
另请注意,"特殊逻辑" for (int i = 1; i < list.Count; i++)可以使用Linq扩展方法实现:foreach(var item in sequence.Skip(1)).
所以,一般比B更喜欢B.
对于C:如果他们不习惯功能风格,这可能会让其他开发人员感到困惑.
至于D:这取决于很多因素.我想对于简单的计算,你不想这样做 - 如果循环体需要一段时间来计算,你只会真正受益于并行化.