【问题标题】:Do unused paramenters in functions slow down the execution of JavaScript?函数中未使用的参数会减慢 JavaScript 的执行速度吗?
【发布时间】:2015-03-06 06:51:07
【问题描述】:

在 javascript 函数中使用未使用的参数会减慢执行速度吗?会不会占用内存?我经常编写带有从未实际使用过的参数的函数,例如函数有一个事件作为参数,但该事件从未用于任何事情。

【问题讨论】:

  • 我经常用从未实际使用过的参数编写函数 - 为什么? O.o
  • 好吧,我的意思是,我在编写函数时添加了参数,然后我以后不需要它们,但我可能会把它们留在那里。有时您有一些示例代码,其中包含不需要的事件或其他参数。我只是想知道是否值得删除这些参数以提高性能。
  • @Andreas 看起来他正在创建 DOM 事件回调 (addEventHandler),并且默认情况下只是将 event 参数添加到函数中,即使它可能不会被使用。很多人都这样做...这也意味着参数 传递(并且在 arguments 中可用),这使得差异比以前更小。
  • 删除未使用的参数以保持代码干净是值得的 - 在函数签名以及调用站点中。由于事件处理程序无论如何都会传递一个事件参数,为了清楚起见,您最好保留这些参数。无论哪种方式,如果性能或内存消耗存在问题,请确定瓶颈并首先寻找更好的算法和数据结构。

标签: javascript performance optimization


【解决方案1】:

减慢执行速度?

运行时间取决于对输入执行的操作。可能是搜索、排序或任何简单的操作。操作的运行时间决定了它的执行速度。因此,当您不传递任何参数时,这意味着没有对该参数执行任何操作,因此运行时间是稳定的。

会占用内存吗?

但就内存分配而言,一般会分配一个Lexical Environment

当函数运行时,在每个函数调用中,新的 LexicalEnvironment 被创建并填充了参数, 变量和嵌套函数声明。

所以对于下面的函数:

function sayHi(name) {
/* LexicalEnvironment = { name: passedvalue, 
                        phrase: undefined }*/  // created at this point.
  var phrase = "Hi, " + name
  alert(phrase)
}

所以当你以sayHi() 调用它时,词法环境看起来像:

LexicalEnvironment = { name: undefined, phrase: undefined};

因此,当解释器解释函数时,每个参数和函数变量都会被分配内存。

当解释器准备开始函数代码执行时, 在运行第一行之前,会创建一个空的 LexicalEnvironment 并且填充了参数、局部变量和嵌套函数。

【讨论】:

  • 虽然我喜欢你的广泛回答,但我认为它错过了问题的重点:性能。
  • @Zeeker,我认为这是不言自明的,当且仅当对参数执行某些操作时,函数的执行速度才会受到影响。已根据您的 cmets 更新了我的答案。
  • @BatScream 不使用函数的参数是否意味着没有对参数执行任何操作?例如,function sayHi(woops) { console.log("whats up"); } 中的参数 woops
【解决方案2】:

JavaScript 无论如何都会将发送给每个函数的参数存储在 arguments 数组中,而不管您是否为它们分配局部变量。

function test() {
    console.log(arguments)
}

test('these','are','passed')

//logs ["these','are',passed']

我的意思是,未使用的参数无论如何都会占用内存,您只是使用另一个变量名来引用它们。

【讨论】:

    【解决方案3】:

    在 javascript 函数中使用未使用的参数会减慢执行速度吗?

    在现代引擎中可能不是(这是微不足道的死代码消除)。无论如何,在堆栈上分配变量是便宜

    它会占用内存吗?

    至少有几个字节用于将函数的主体保存为字符串。

    我经常用从未实际使用过的参数编写函数,例如函数有一个事件作为参数,但该事件从未用于任何事情。

    您不应该关心没有基准测试的微优化。不要试图超越编译器,V8 和 SpiderMonkey 在优化代码方面做得很好。

    【讨论】:

      【解决方案4】:

      我对这个问题的一个子集感兴趣:生成未使用参数的代码是否已评估?我的用例是调试日志消息:当我将日志级别设置为低于“调试”时,保留调试代码会减慢我的脚本吗?我在https://jsperf.com/log-parameters/1 进行了基准测试以找出答案。这表明代码已经过评估并且确实减慢了脚本的速度。

      测试说明

      准备代码

      Benchmark.prototype.setup = function() {
      
        var generate_message = function() {
          // Do some calculations to generate a dummy message.
          var s = ''
          for (var i = 1; i < 512; i++) {
            var a = Math.random()
            var b = Math.random()
            s += String.fromCharCode(48 + Math.floor(128*a*b))
          }
          return s
        }
      
        var Log = {
          level: 1, /* 1 = FATAL, 4 = DEBUG */
          fatal: function(msg) {this.log(1, msg)},
          debug: function(msg) {this.log(4, msg)},
          log: function(lvl, msg) {
                 if (lvl <= this.level) {
                   if (typeof msg === 'function') msg = msg()
                   console.log([new Date(), lvl, msg].join('::'))
                 }
               },
        }
      
      };
      

      测试 1:总是评估

      Log.debug(generate_message())
      

      测试 2:有条件地评估

      Log.debug(generate_message)
      

      结果

      总是评估

      36,047 ±1.45% 操作/秒

      有条件地评估

      30,326,171 ±5.55% 操作/秒

      【讨论】:

      • if 什么都没有。 if 检查会导致减速。
      猜你喜欢
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 2015-12-25
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多