I recently asked关于没有副作用的功能程序,并了解这对于使并行化任务变得微不足道意味着什么。具体来说,“纯粹”的功能使这一点变得微不足道,因为它们没有任何副作用。
我最近也在研究LINQ和lambda表达式,因为我在StackOverflow上涉及枚举的例子很多次。这让我想知道在C#中并行化枚举或循环是否“更容易”。
lambda表达式“纯粹”是否足以实现平凡的并行化?也许这取决于你在表达中做了什么,但它们能够足够纯粹吗?在C#中,这样的事情在理论上是可行的/微不足道的吗?:
例如,假设我在游戏循环中有一堆对象(因为我正在开发游戏并考虑多线程的可能性)并且必须每帧都对它们做一些事情,上面是拉扯琐碎?看看IEnumerable似乎它只跟踪当前的位置,所以我不确定我是否可以使用普通的泛型集合来将枚举分解为“块”。
对此问题感到抱歉。我使用上面的子弹而不是伪代码,因为我甚至不知道如何编写伪代码。我的.NET知识纯粹是简单的业务,我是代表和线程等的新手。我主要想知道上面的方法是否适合追求,如果代表/ lambdas不必担心什么时候它涉及到它们的并行化。
答案 0 :(得分:17)
首先,请注意,为了“纯粹”,方法必须不仅没有副作用。在给出相同的参数时,它也必须始终返回相同的结果。因此,例如,“Math.Sin”方法是纯粹的。你喂12,它给你回罪(12),每次都是一样的。方法GetCurrentTime()即使没有副作用也不纯;每当你调用它时,它都会返回一个不同的值,无论你传入什么参数。
另请注意,纯方法确实不应该抛出异常;例外情况被视为我们目的的可观察副作用。
第二,是的,如果你可以推断一个方法的纯度,那么你可以做一些有趣的事情来自动并行化它。麻烦的是,几乎没有方法实际上是纯粹的。此外,假设你有一个纯粹的方法;因为纯方法是备忘的完美候选者,并且由于memoization引入了副作用(它改变了缓存!)因此采用纯粹的方法然后使它们变得不纯是非常有吸引力的。
正如Joe Duffy所说,我们真正需要的是一种“驯服副作用”的方法。某种方法在方法周围绘制一个方框并说“此方法不是无副作用,但其副作用在此框外不可见”,然后使用 事实驱动安全的自动并行化。
我想找出一些方法将这些概念添加到像C#这样的语言中,但这里完全是蓝天开放研究问题;没有任何意图或暗示的承诺。
答案 1 :(得分:13)
Lambda的应该是纯粹的。然后,FrameWork提供自动并行化,只需对LINQ查询(PLINQ)进行简单的.AsParallel
添加。
但它不是自动的或保证的,程序员有责任使它们保持纯净。
答案 2 :(得分:3)
lambda是否纯粹与它正在做的事情有关。作为一个概念,它既不纯粹也不纯洁。
例如:以下lambda表达式是不纯的,因为它正在读取和写入正文中的单个变量。并行运行会产生竞争条件。
var i = 0;
Func<bool> del = () => {
if ( i == 42 ) { return true; }
else ( i++ ) { return false; }
};
相反,以下代表是纯粹的,没有竞争条件。
Func<bool> del = () => true;
答案 3 :(得分:3)
对于循环部分,您还可以使用Parallel.For
和Parallel.ForEach
作为游戏中对象的示例。这也是.net 4的一部分,但你可以下载它。
答案 4 :(得分:2)
有13篇部分内容涉及.NET 4.0 here中新的Parallelism支持。它还包括对第7部分中LINQ和PLINQ的讨论。这是一个很好的阅读,所以请查看