2

在 JavaScript 中,我们可以将函数组合定义为使用带有两个函数 f 和 g 的函数来生成一个新函数:

function o(f, g) {
  return function(x) {
   return f(g(x));
  }
 }

这似乎很明显,但我的问题是,运行时解释器/编译器是否实际计算f(g(x))?

假设我们有一些大数据,例如具有许多元素的数组,并且先前计算的先前组合的函数 o 作为f(g(x))是否比未组合的f(g(x))更快?

也许,在这种情况下,o(f, g)仅仅是f(g(x))的宏表达式?

如果它是一个宏,也许,性能没有太大区别?

这可能取决于运行时环境,我对 Chrome/node.js 的 V8 引擎特别感兴趣。

Haskell 作为一种惰性求值策略语言,理论上可以组合函数,我说的对吗?GHC 真的计算组成函数吗?

4

2 回答 2

2

不,函数调用o(f, g)将完全返回匿名函数:

function (x) {
    return f(g(x));
}

然后,只有在您调用该匿名函数时,g(x)才会执行,然后f将执行g(x). 每次您调用该匿名函数gf执行时,一个接一个。f(g(x))因此,由于额外匿名函数的轻微开销,使用组合函数将比在代码中的任何地方手动调用慢一点。

例子:

function o(f, g){
    return function(x) {
        return f(g(x));
    }
}

function addTo5(x){
    return x + 5;
}

function multiplyBy(x){
    return function(y){
        return x*y;
    }
}

var composed = o(multiplyBy, addTo5);
composed(5)(3); // Slightly slower than multiplyBy(addTo5(5))(3)

jsperf

于 2013-07-17T18:48:21.827 回答
0

在调用由 . 返回的组合函数之前,不会执行任何计算o。这个新函数只是跟踪什么fg是什么,并在您传入时调用它们x,评估并返回最终结果。

于 2013-07-17T18:48:34.777 回答