更好的多线程:单一功能或集合功能

时间:2009-06-13 19:07:57

标签: c# .net parallel-processing immutability

我不知道我的说法是否正确,但是举一个简单的例子,假设我们有一个Point3值的集合(比如1M)。

我们有一个名为Offset的方法,它会在这些值上添加另一个Point3值,返回新的Point3值。假设该方法是静态的。

Point3类型是不可变的。

问题是,我应该有这样的方法:

public static Point3 Offset ( Point3 a, Point3 b )

public static IEnumerable<Point3> Offset ( IEnumerable<Point3> a, IEnumerable<Point3> b )

对我来说,#1似乎是将任务分解为不同线程的单独任务的更好选择。

你怎么看?和#1或#2的优势?

4 个答案:

答案 0 :(得分:2)

你应该拥有第一个,并且第二个呼叫是第一个。

答案 1 :(得分:2)

#1看起来更简单,更清洁,您可以始终从外部并行化。我没有理由只使用#2,除非你忽略了一个关键的细节。如果您决定以相同的方式定期并行化这种循环,请将#2调用#1。

答案 2 :(得分:1)

我的答案都是。我喜欢最简单的功能,所以#1很好。同时,在列表上操作的便捷方法也很有用,如果合适的话,它可以完成产生线程的艰苦工作。

我的Java之一(好吧,几乎所有语言,但Java足够新,他们本应该知道的更好)是他们仍然没有做好基础库利用多线程或提供的优势许多机制来帮助开发人员。确实应该有一个通用函数来“将此函数应用于此列表中的所有元素”,并使该函数计算出可用的核心数,列表的大小,开销是多少,并相应地进行优化。

答案 3 :(得分:1)

选项1是逻辑核心操作。使用.NET 4.0,您可以使用Zip运算符实现与选项2相同的操作。从记忆中,而不是:

var newPoints = Offset(firstPoints, secondPoints);
你会写:

var newPoints = firstPoints.Zip(secondPoints, (p1, p2) => Offset(p1, p2));

如果您使用的是.NET 3.5,也可以考虑在Offset上设置Point3扩展方法。 (或者,如果您控制Point3类型,这听起来像是一个逻辑添加 - 在(p1, p2) => p1 + p2的调用中写Zip会很好。

如果您没有使用.NET 4.0但Zip对您有吸引力,我们在MoreLINQ中有一个实现 - 这非常简单。

到目前为止,没有任何与多线程有关...现在我不知道在.NET 4.0中是否存在Zip的PLINQ实现,但是有一个是有意义的,IMO。