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

Do unused paramenters in functions slow down the execution of JavaScript?

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

slow down execution?

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

Does it take up memory?

但是就内存分配而言,一般都是分配一个Lexical Environment.

When the function runs, on every function call, the new LexicalEnvironment is created and populated with arguments, variables and nested function declarations.

所以对于下面的函数:

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

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

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

因此,每个参数和函数变量都是在解释器解释函数时分配内存的。

When the interpreter is preparing to start function code execution, before the first line is run, an empty LexicalEnvironment is created and populated with arguments, local variables and nested functions.

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

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

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

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

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

Does having unused parameters in javascript functions slow down execution?

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

Does it take up memory?

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

I often write functions with parameters that are never actually used for example function has an event as a parameter, but the event is never used for anything.

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

我对这个问题的一个子集感兴趣:是否对生成未使用参数的代码进行了评估?我的用例是调试日志消息:当我将日志级别设置为低于 "debug" 时,留在调试代码中会减慢我的脚本吗?我 运行 在 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% ops/sec

有条件地评估

30,326,171 ±5.55% ops/sec