“锁定”JavaScript 对象有什么性能优势?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8435080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 03:26:33  来源:igfitidea点击:

Any performance benefit to "locking down" JavaScript objects?

javascriptecmascript-5javascript-1.8

提问by callum

JavaScript 1.8.5 (ECMAScript 5) adds some interesting methods that prevent future modificationsof a passed object, with varying degrees of thoroughness:

JavaScript 1.8.5 (ECMAScript 5) 添加了一些有趣的方法,以不同程度的彻底性防止将来修改传递的对象:

Presumably the main point of these is to catch mistakes: if you know that you don't want to modify an object after a certain point, you can lock it down so that an error will be thrown if you inadvertently try to modify it later. (Providing you've done "use strict";that is.)

大概这些的主要目的是捕捉错误:如果你知道你不想在某个点之后修改一个对象,你可以锁定它,这样如果你以后不经意地尝试修改它就会抛出错误。(前提是你已经这样做"use strict";了。)

My question:in modern JS engines such as V8, is there any performance benefit (eg, faster property look-ups, reduced memory footprint) in locking down objects using the above methods?

我的问题:在 V8 等现代 JS 引擎中,使用上述方法锁定对象是否有任何性能优势(例如,更快的属性查找、减少的内存占用)?

(See also John Resig's nice explanation– doesn't mention performance, though.)

(另见John Resig 的好解释——不过没有提到性能。)

回答by Jan Molak

There's been no differencein performance since at least Chrome 47.0.2526.80 (64-bit).

还有的是没有什么区别,因为至少铬47.0.2526.80(64位)的性能。

Testing in Chrome 6.0.3359 on Mac OS 10.13.4
-----------------------------------------------
Test               Ops/sec
non-frozen object  106,825,468  ±1.08%  fastest
frozen object      106,176,323  ±1.04%  fastest

Performance test (available at http://jsperf.com/performance-frozen-object):

性能测试(可在http://jsperf.com/performance-frozen-object 获得):

  const o1 = {a: 1};
  const o2 = {a: 1};

  Object.freeze(o2);

  // Non-frozen object:
  for(var key in o1);

  // Frozen object:
  for(var key in o2);

Update 30.10.2019: There's no difference in performance on Chrome 78.0.3904(64-bit)

2019 年 10 月 30 日更新:Chrome 78.0.3904(64 位)上的性能没有差异

Update 17.09.2019: There's no difference in performance on Chrome 76.0.3809(64-bit)

2019 年 917 日更新:Chrome 76.0.3809(64 位)上的性能没有差异

Update 03.05.2018: There's no difference in performance on Chrome 66.0.3359(64-bit)

2018 年 5月 3 日更新:Chrome 66.0.3359(64 位)上的性能没有差异

Update 06.03.2017: There's no difference in performance on Chrome 56.0.2924(64-bit)

2017 年 3月 6 日更新:Chrome 56.0.2924(64 位)上的性能没有差异

Update 13.12.2015: There's no difference in performance on Chrome 47.0.2526.80(64-bit)

2015 年 12 月 13 日更新:Chrome 47.0.2526.80(64 位)上的性能没有差异



With Chrome 34, a frozen object performs slightly better than a non-frozen one in @pimvdb's test case (results below). The difference, however doesn't seem to be large enough to justify using this technique for performance benefits.

使用 Chrome 34,在@pimvdb 的测试用例中,冻结对象的性能略好于非冻结对象(结果如下)。然而,差异似乎不足以证明使用这种技术来获得性能优势是合理的。

http://jsperf.com/performance-frozen-object

http://jsperf.com/performance-frozen-object

Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  105,250,353  ±0.41%  3% slower
frozen object      108,188,527  ±0.55%  fastest

Running @kangax's test cases shows that both versions of the object perform pretty much the same:

运行@kangax 的测试用例表明该对象的两个版本的性能几乎相同:

http://jsperf.com/performance-frozen-object-prop-access

http://jsperf.com/performance-frozen-object-prop-access

Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  832,133,923  ±0.26%  fastest
frozen object      832,501,726  ±0.28%  fastest

http://jsperf.com/http-jsperf-com-performance-frozen-object-instanceof

http://jsperf.com/http-jsperf-com-performance-frozen-object-instanceof

Testing in Chrome 34.0.1847.116 on OS X 10.9.2
----------------------------------------------
Test               Ops/sec
non-frozen object  378,464,917  ±0.42%  fastest
frozen object      378,705,082  ±0.24%  fastest

回答by pimvdb

Update:Since this answer was originally written, the bug in V8 that caused this issuehas been fixed. See the answer by Jan Molakfor more info.

更新:由于此答案最初是编写的,因此已修复导致此问题的 V8 中的错误。有关更多信息,请参阅Jan Molak 的回答



In Google Chrome (so V8, that is), a frozen object iterates 98% slowerthan a regular object.

在 Google Chrome(即 V8)中,冻结对象的迭代速度比常规对象慢 98%

http://jsperf.com/performance-frozen-object

http://jsperf.com/performance-frozen-object

Test name*              ops/sec

non-frozen object    32,193,471
frozen object           592,726

Probably this is because those functions are relatively new and probably not optimized yet (but that's just my guess, I honestly don't know the reason).

可能这是因为这些功能相对较新,可能还没有优化(但这只是我的猜测,老实说我不知道​​原因)。

Anyhow, I really do not recommed using it for performance benefits, as that apparently does not make sense.

无论如何,我真的不建议使用它来提高性能,因为这显然没有意义。



* The code for the test is:

* 测试代码为:

var o1 = {a: 1};
var o2 = {a: 1};

Object.freeze(o2);

Test 1 (non-frozen object):

测试 1(非冷冻对象):

for(var key in o1);

Test 2 (frozen object):

测试 2(冷冻物体):

for(var key in o2);

回答by Raynos

In theory freezing an object allows you to make stronger guarantees about the shape of an object.

理论上,冻结对象可以让您对对象的形状做出更有力的保证。

This means the VM can compact the memory size.

这意味着 VM 可以压缩内存大小。

It means the VM can optimize property lookups in the prototype chain.

这意味着 VM 可以优化原型链中的属性查找。

It means any live references just became not live because the object cannot change anymore.

这意味着任何实时引用都变得无效,因为对象无法再更改。

In practice JavaScript engines do not make these aggressive optimization yet.

在实践中,JavaScript 引擎还没有进行这些积极的优化。

回答by llambda

V8 has optimized Object.freeze as of Jun 20, 2013. And Object.seal and Object.preventExtensions as of Dec 10, 2014. See issue https://code.google.com/p/chromium/issues/detail?id=115960

截至 2013 年 6 月 20 日,V8 已优化 Object.freeze。截至 2014 年 12 月 10 日,已优化 Object.seal 和 Object.preventExtensions。请参阅问题https://code.google.com/p/chromium/issues/detail?id= 115960

回答by tomekwi

If you're interested in the performance of object creation(literal vs frozen vs sealed vs Immutable.Map), I've created a test on jsPerfto check that out.

如果您对对象创建的性能(文字 vs 冻结 vs 密封 vs Immutable.Map)感兴趣,我已经在 jsPerf上创建了一个测试来检查一下。

So far I've only had the opportunity to test it in Chrome 41 and Firefox 37. In both browsers the creation of a frozen or sealed object takes about three times longerthan the creation of a literal – whereas the Immutable.Mapperforms about 50 times worse than the literal.

到目前为止,我只有机会在 Chrome 41 和 Firefox 37 中对其进行测试。在这两种浏览器中,创建冻结或密封对象所需的时间大约是创建文字的Immutable.Map时间的三倍——而性能却比创建文本要差 50 倍。字面意思。

回答by jAndy

The only reason I see for those methods in production code is, that you can have sealed or frozen objects, for integrity purposes.

我在生产代码中看到这些方法的唯一原因是,出于完整性目的,您可以密封或冻结对象。

For instance, I write a little library, which works just great and offers you a set of methods in an object, but I don't want to you to change or overwrite any of my properties or methods. I'm not saying I can prevent you from doing that, but I can try to prevent you do it by accident which maybe is more important.

例如,我编写了一个小库,它工作得很好,并为您提供了对象中的一组方法,但我不想让您更改或覆盖我的任何属性或方法。我不是说我可以阻止你这样做,但我可以尝试阻止你不小心这样做,这可能更重要。

Also, those methods are easy to 'shim' in environment which doen't know about them, by just returning the original object. Of course it would have no effect then.

此外,这些方法很容易在不了解它们的环境中“填充”,只需返回原始对象即可。到时候当然不会有什么影响。

I don't see any performance related reasons to do this.

我没有看到任何与性能相关的原因。