在JavaScript中,我们可以将function composition定义为使用带有两个函数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实际上是否计算构成函数?
答案 0 :(得分:2)
不,函数调用o(f, g)
将完全返回匿名函数:
function (x) {
return f(g(x));
}
然后,只有当您调用该匿名函数时,g(x)
才会执行,然后f
将对g(x)
的结果执行。每次调用匿名函数g
和f
都会一个接一个地执行。因此,使用组合函数将比在代码中的任何地方手动调用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)
答案 1 :(得分:0)
在调用o
返回的组合函数之前,不会执行任何计算。这个新函数只是跟踪f
和g
是什么,并在您通过x
,评估并返回最终结果时调用它们。