简体   繁体   English

JavaScript中的嵌套功能和性能?

[英]Nesting functions and performance in javascript?

Some of coworkers are saying that nesting functions is bad for performance and I wanted to ask about this. 一些同事说嵌套功能不利于性能,我想问一下。

Lets say I have the function: 可以说我有以下功能:

function calculateStuff() {
    function helper() {
    // helper does things
    }
    // calculateStuff does things
    helper();
}

helper is a private function that is only used inside calculateStuff. helper是一个私有函数,仅在calculateStuff内部使用。 That's why I wanted to encapsulate this inside calculateStuff. 这就是为什么我想将其封装在calculateStuff中。

Is this worse performance wise than doing: 这是否比执行更差的性能明智:

function helper() {

}

function calculateStuff() {
    helper();
}

Notice that in the second case, I expose helper to my scope. 请注意,在第二种情况下,我将帮助程序暴露给我的作用域。

In theory, there's a potential performance impact, in that you need to create a new closure context for helper every time calculateStuff is called (because it might reference variables from the enclosing scope). 从理论上讲,有一个潜在的性能影响,你需要创建一个新的闭包上下文帮助calculateStuff被称为(因为它可能会从封闭范围内引用变量)的时间。

I'm pretty sure that the JIT compiler in most JavaScript engines should be able to tell that you aren't actually accessing any variables from the parent context, and just skip binding all of those values. 很确定大多数JavaScript引擎中的JIT编译器应该能够告诉您实际上不是从父上下文访问任何变量,而只是跳过绑定所有这些值。 I may be missing some edge case where this isn't generally possible, but it seems straighforward-enough. 我可能会错过一些通常无法实现的优势,但似乎已经足够了。

In any case, we're talking about nanoseconds of overhead per iteration, so unless your code is executed a lot , you'd never notice the time difference. 无论如何,我们谈论的是每次迭代的纳秒级开销,因此,除非您的代码执行得很多 ,否则您永远不会注意到时间差。 If in doubt, profile it and check... 如有疑问,请对其进行分析并检查...


I decided to follow my own advice, and profile this on jsperf , with Safari 9. I used the do-nothing functions as provided in the original question, to highlight the overhead of just calling a nested function: 我决定遵循我自己的建议,并使用Safari 9 在jsperf上对此进行概要分析 。我使用了原始问题中提供的不执行任何功能,以强调仅调用嵌套函数的开销:

Nested functions: 136,000,000 calls per second 嵌套函数:每秒136,000,000次调用

Flat functions: 1,035,000,000 cals per second 固定功能:每秒1,035,000,000卡路里

Oriol's IIFE version : 220,000,000 cals per second Oriol的IIFE版本 :每秒220,000,000卡

Clearly the flat functions are much faster than either of the alternative versions. 显然,平板功能比任何替代版本快得多 However , think about the magnitude of those numbers - even the "slow" version only adds 0.007 microseconds to the execution time. 但是 ,请考虑这些数字的大小-即使是“慢速”版本也只会增加0.007微秒的执行时间。 If you do any kind of calculation or DOM manipulation in that function, it'll absolutely dwarf the overhead of the nested function. 如果您在该函数中执行任何类型的计算或DOM操作,则绝对会使嵌套函数的开销相形见war。

With your first code, at each call of calculateStuff , a new copy of helper will be created. 有了您的第一个代码,在每次调用calculateStuff ,新副本helper将被创建。

With your second code, all calls will share the same helper , but it will pollute the outer scope. 使用您的第二个代码,所有调用将共享同一个helper ,但是它将污染外部作用域。

If you want to reuse helper without polluting the outer scope, you can use an IIFE: 如果要重用helper而不污染外部作用域,则可以使用IIFE:

var calculateStuff = (function () {
  function helper() {
    // helper does things
  }
  return function() {
    // calculateStuff does things
    helper();
  }
})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM