JavaScript 1.8.5(ECMAScript 5)添加了一些有趣的方法,防止将来对所传递的对象进行修改,并具有不同程度的完整性:
- Object.preventExtensions(obj)
- Object.seal(obj)
- Object.freeze(obj)
大概这些要点是捕捉错误:如果您知道不想在某个点之后修改对象,则可以将其锁定,以便在无意中尝试修改时抛出错误以后再说. (证明您已经完成了"use strict";.)
我的问题:在现代JS引擎(例如V8)中,使用上述方法锁定对象是否有任何性能优势(例如,更快的属性查找,更少的内存占用)?
(另请参见约翰·雷西格的漂亮解释 –不会提及性能.)
解决方案至少从Chrome 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性能测试(位于 jsperf/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);更新30.10.2019 :Chrome 78.0.3904 (64位)
的性能没有差异更新17.09.2019 :Chrome 76.0.3809 (64位)上的性能没有差异
更新03.05.2018 :Chrome 66.0.3359 (64位)上的性能没有差异
更新06.03.2017 :Chrome 56.0.2924 (64位)
的性能没有差异2015年12月13日更新:Chrome 47.0.2526.80 (64位)上的性能没有差异
使用Chrome 34,在@pimvdb的测试案例中,冻结对象的性能要比非冻结对象好一些(结果如下).但是,差异似乎还不够大,不足以证明使用此技术可获得性能上的好处.
jsperf/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运行@kangax的测试用例表明,该对象的两个版本执行的功能几乎相同:
jsperf/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% fastestjsperf/http-jsperf-com-性能冻结对象实例
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% fastestJavaScript 1.8.5 (ECMAScript 5) adds some interesting methods that prevent future modifications of a passed object, with varying degrees of thoroughness:
- Object.preventExtensions(obj)
- Object.seal(obj)
- Object.freeze(obj)
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.)
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?
(See also John Resig's nice explanation – doesn't mention performance, though.)
解决方案There's been no difference in performance since at least Chrome 47.0.2526.80 (64-bit).
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% fastestPerformance test (available at jsperf/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)
Update 17.09.2019: There's no difference in performance on Chrome 76.0.3809 (64-bit)
Update 03.05.2018: There's no difference in performance on Chrome 66.0.3359 (64-bit)
Update 06.03.2017: There's no difference in performance on Chrome 56.0.2924 (64-bit)
Update 13.12.2015: There's no difference in performance on Chrome 47.0.2526.80 (64-bit)
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.
jsperf/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% fastestRunning @kangax's test cases shows that both versions of the object perform pretty much the same:
jsperf/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% fastestjsperf/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
更多推荐
任何性能上的好处是“锁定"了虚拟机. JavaScript对象?
发布评论