javascript中的嵌套函数和性能?
一些同事说嵌套函数不利于性能,我想问一下这一点 假设我有以下功能:javascript中的嵌套函数和性能?,javascript,performance,nested-function,Javascript,Performance,Nested Function,一些同事说嵌套函数不利于性能,我想问一下这一点 假设我有以下功能: function calculateStuff() { function helper() { // helper does things } // calculateStuff does things helper(); } helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中 这是否比执行以下操作更糟糕: fun
function calculateStuff() {
function helper() {
// helper does things
}
// calculateStuff does things
helper();
}
helper是一个私有函数,仅在calculateStuff中使用。这就是为什么我想把它封装在calculateStuff中
这是否比执行以下操作更糟糕:
function helper() {
}
function calculateStuff() {
helper();
}
请注意,在第二种情况下,我将帮助程序公开到我的作用域。使用第一个代码,每次调用
calculateStuff
,都将创建一个新的helper
副本
对于第二个代码,所有调用将共享相同的帮助程序
,但它会污染外部作用域
如果您想在不污染外部范围的情况下重用helper
,可以使用IIFE:
var calculateStuff = (function () {
function helper() {
// helper does things
}
return function() {
// calculateStuff does things
helper();
}
})();
从理论上讲,这可能会对性能产生影响,因为每次调用calculateStuff时都需要为helper创建一个新的闭包上下文(因为它可能引用封闭范围中的变量) 我非常确信,大多数JavaScript引擎中的JIT编译器应该能够判断您实际上没有从父上下文访问任何变量,而只是跳过绑定所有这些值。我可能遗漏了一些边缘案例,在这些案例中,这通常是不可能的,但这似乎已经足够严格了 在任何情况下,我们讨论的都是每次迭代的纳秒开销,因此除非您的代码被大量执行,否则您永远不会注意到时间差。如果有疑问,请对其进行配置并检查
我决定听从自己的建议,用Safari 9来描述这一点。我使用了原始问题中提供的“不做任何事情”函数,以强调仅调用嵌套函数的开销:
function calculateStuff() {
function helper() {
// helper does things
}
// calculateStuff does things
helper();
}
嵌套函数:每秒136000000次调用
平板功能:1035000000卡/秒
:220000000卡/秒
显然,平面函数比任何一种替代版本都要快得多。然而,想想这些数字的大小——即使是“慢”版本也只会增加0.007微秒的执行时间。如果在该函数中执行任何类型的计算或DOM操作,都会大大降低嵌套函数的开销。您仍然会污染外部范围,虽然它不是全局作用域。@MinusFour究竟用什么污染它?@MinusFour它创建了一个中间作用域并污染了它,而不是外部作用域。我只是说中间作用域也可以被视为外部作用域(至少从匿名函数上下文来看)。@MinusFour这毫无意义。“每次调用calculateStuff时为helper创建一个新的闭包上下文(因为它可能引用封闭范围中的变量)。“---因此,如果它不涉及任何自由变量,那么根本就没有这种影响?如果这是您试图表达的,那么它是错误的。@zerkms:是的,如果它不引用自由变量,特别是如果它不是从该范围导出的,那么函数可以并且将被内联。“怎么回事?”虫族:我和马克都没这么说。当然,该标准对性能没有任何要求(ES5映射和集除外),但Mark是对的,大多数JIT编译器(即实际实现)能够跳过在堆上创建函数对象甚至闭包上下文。@Bergi是对的,但这意味着绑定词法作用域是唯一的开销。而函数的创建一般来说并不便宜。因此,我在这里的观点是,答案强调了作用域的绑定,而忽略了创建函数对象的一个重要部分。@zerkms:在任何情况下,答案都应该是“如果有疑问,请分析它”单独:-)我投票结束这个问题,因为性能指标最好由jsperf处理,并且随着浏览器的发展,保存期很短。不要询问其他人关于性能的问题。如果有疑问,请测量它。