-1

我不知道我的措辞是否正确,但举个简单的例子,假设我们有一个 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

4 回答 4

2

您可能应该拥有第一个,并让第二个呼叫第一个。

于 2009-06-13T19:13:35.290 回答
2

#1 看起来更简单、更干净,你总是可以从外部并行化它。我看不出有理由专门使用#2,除非你忽略了一个关键的细节。如果您决定要以相同的方式定期并行化这种循环,请让 #2 调用 #1。

于 2009-06-13T19:22:14.643 回答
1

我的答案是两者兼而有之。我喜欢尽可能简单的功能,所以#1 很好。同时,对列表进行操作的便捷方法非常有用,如果合适的话,可以完成繁重的线程生成工作。

我对 Java 的不满之一(嗯,几乎所有语言,但 Java 足够新,他们应该更了解)是他们仍然没有做好让基础库利用多线程的工作,或者提供了许多机制来帮助开发人员。确实应该有一个通用函数来执行“将此函数应用于此列表中的所有元素”,并让该函数确定有多少内核可用,列表有多大,开销是多少,并进行相应的优化。

于 2009-06-13T19:30:04.547 回答
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 但对您有吸引力,我们在MoreLINQZip中有一个实现- 它非常简单。

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

于 2009-06-13T22:40:28.333 回答