将复杂对象传递给 javsacript 函数与单个 var 的性能差异?

Tre*_*est 0 javascript performance object

考虑一个作用于我传递的复杂对象的一个​​元素的函数。我可以把它写成:

function foo(object) {
  bar(object.item)
}
Run Code Online (Sandbox Code Playgroud)

或者

function foo(item) {
  bar(item);
}
Run Code Online (Sandbox Code Playgroud)

如果我可以选择,将对象的单个元素传递给函数与传递整个对象并拉出我需要的部分是否有任何性能优势?

即,调用是否更有效:

 foo(object);
Run Code Online (Sandbox Code Playgroud)

并传递整个对象让 foo 处理,或

 foo(object.item);
Run Code Online (Sandbox Code Playgroud)

哪个只通过单个项目?


更新:看起来在评论到达之前我找不到术语是 Javascript 是pass-by-reference还是pass-by-value

由于对象是在 Javascript 中通过引用传递的(有一些重要的警告),所以我传递的对象有多大应该没有区别。

有趣的阅​​读:

https://medium.freecodecamp.org/understanding-by-reference-vs-by-value-d49139beb1c4

Cer*_*nce 5

对象属性访问是一个有点比普通值的访问更加昂贵。(警告,以下代码段会暂时阻止您的浏览器,具体取决于您计算机的规格:)

(() => {
  const obj = { foo: 'bar' };

  const t0 = performance.now();
  for (let i = 0; i < 1e9; i++) {
    obj.foo;
  }
  const t1 = performance.now();

  const { foo } = obj;
  for (let i = 0; i < 1e9; i++) {
    foo;
  }
  const t2 = performance.now();
  console.log('Object property access: ' + (t1 - t0));
  console.log('Variable access: ' + (t2 - t1));
})();
Run Code Online (Sandbox Code Playgroud)

差异很小,但它就在那里。当您有 时obj.prop,解释器首先必须查找obj引用的内容,然后必须查找prop属性obj以获取值。因此,当您要查找的值已经在独立变量中时,它会更容易一些 - 获得它所需的一切就是让解释器查找该变量。

但是,对于您提到的示例,无论如何,您都将进行一次对象查找和一次普通值查找:

foo(object); // 1 variable lookup
function foo(object) {
  bar(object.item) // 1 object property lookup
}

// vs

foo(object.item); // 1 object property lookup
function foo(item) {
  bar(item); // 1 variable lookup
}
Run Code Online (Sandbox Code Playgroud)

如果多次foo使用该.item属性会有所不同。例如,如果有:foo

foo(object); // 1 variable lookup
function foo(object) {
  bar(object.item) // 1 object property lookup
  baz(object.item) // 1 object property lookup
}
Run Code Online (Sandbox Code Playgroud)

这将需要两个对象属性查找,这意味着item单独传递(非常轻微)更有效。

综上所述,差别确实微乎其微。正如您在代码段中看到的那样,它需要10 亿次迭代(至少在我的机器上)才能可靠地看到差异,即便如此,改进也只有约 5-10% 左右,至少对我来说在 Chrome 上是这样。在 99% 的情况下,这都不值得担心。代码可读性更重要。

  • TBH 我很惊讶[编译器早餐没有吃你的微基准测试](https://mrale.ph/blog/2012/12/15/microbenchmarks-fairy-tale.html) 并将该循环优化为无- 操作。 (2认同)
  • 知道了。于是厚重的书(对象)就放在书架上,代码谈起它,偶尔查一下书里的东西,但实际上并没有把书从一个函数交给另一个函数。无论何时发生,查找都需要一定的(少量)时间。 (2认同)