【问题标题】:Why does declarative coding lend it self to parallel computing为什么声明式编码适合并行计算
【发布时间】:2016-10-28 14:20:15
【问题描述】:

Mostly Adequate Guide drboolean 中提出“声明式编码适用于并行计算”。举个例子:

// imperative
var authenticate = function(form) {
  var user = toUser(form);
  return logIn(user);
};

// declarative
var authenticate = compose(logIn, toUser);

我认为顺序保留在撰写中(从右到左)。那么声明式编码为并行计算提供了哪些额外的功能呢?

【问题讨论】:

    标签: javascript parallel-processing declarative


    【解决方案1】:

    我同意你的命令,至少在authenticate 示例中必须保留它。

    关于可能使声明式成为一种对并行更友好的范式的特性,这一切都与模块化有关。您可以在第一个示例(汽车示例)中更好地看到它:

    // imperative
    var makes = [];
    for (var i = 0; i < cars.length; i++) {
      makes.push(cars[i].make);
    }
    
    // declarative
    var makes = cars.map(function(car) { return car.make; });
    

    在这里,声明式版本是用一个单独的函数编写的,该函数可以异步运行,而在命令式版本中,您只需将一些代码与其余代码混合。

    声明式设计只是让一些部分更容易包装在不同的过程中。

    【讨论】:

      【解决方案2】:

      我认为该指南在这一点上有点误导,在此声明之前使用 compose 作为示例。

      compose 的情况下,声明式风格不允许并行计算,因为即使使用composetoUser 仍然必须在logIn 之前执行,因为它取决于它的输出!

      我认为map 示例更适合说明这一点。虽然你必须一步一步地执行 for 循环,因为你真的不知道下一步会是什么样子,如果你还没有完成上一步,你就不能真正完成所有步骤一次。另一方面,当您使用map 时,您给它一个纯函数,该函数在集合的每个项目上执行。该函数是一个原子动作,它的执行不依赖于函数之前或之后的执行。因此,您可以同时并行执行它们。

      但是,在指南中也提到了一个重要的补充,但在你的引用中被删掉了,那就是函数必须是纯的(这意味着它们不会改变它们的数据结构)操作”,而是返回一个新的)。一个很好的例子是:

      // impure
      var impureSquared = function (list) {
        for (var i = 0; i < list.length; i++) {
          list[i] = list[i] * list[i];
        }
      }
      
      // pure
      var pureSquared = function (list) {
        return list.map(function (item) {
           return item * item;
        }
      }
      

      如果您要在两个线程中对同一数据结构并行运行不纯函数,您可能不会得到您期望的结果,因为数据结构在每个线程中被此函数更改了两次。另一方面,如果您对纯函数执行相同操作,则两个线程都将获得预期的结果,而不会相互干扰。

      我认为执行原子操作的纯函数的概念实际上对于并行执行比声明式编程更重要。您通常只是碰巧这样做,同时以声明性样式进行编码。

      话虽如此,我应该补充一点,javascript 通常是一种单线程语言,所以当您谈论并行计算时,它并不是真正要谈论的语言;)

      【讨论】:

      • 那么您是否暗示在 JavaScript 中实现 map 涉及对 iterable 中所有元素的并行执行,但是这不称为并行计算?
      • 不!对不起,如果这令人困惑,我会尝试澄清一下。首先,您要知道,Javascript 通常是一种单线程语言(在特定情况下有一些例外..)。因此,它永远不会真正并行运行任何东西,无论是什么,或者你如何编码。
      • 尽管如此,虽然我描述的概念适用于任何语言,只是因为您使用map,但这并不意味着您也可以并行执行它!同样使用“传统”for循环并不一定意味着您不能并行运行。如果你应用这些原则,继续让你的代码并行运行会容易得多,因为当突然并行时,你不必考虑太多额外的事情。它基本上只是理论上可以更好地扩展,无论你是否扩展它。
      • 如果这让您感到困惑,我很抱歉,但我只是使用了 javascript,因为它是您提交问题所用的语言。如果您想以某种语言查看类似的内容,您实际上可以并行的地方,请查看 Java 中的 parallel streams
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-15
      • 2011-07-03
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多