Any performance benefit to “locking down” JavaScript objects?

后端 未结 6 1981
Happy的楠姐
Happy的楠姐 2021-02-02 05:18

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

<
相关标签:
6条回答
  • 2021-02-02 05:32

    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.

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

    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.

    0 讨论(0)
  • 2021-02-02 05:33

    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%  fastest
    

    Performance test (available at 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)

    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.

    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:

    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

    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
    
    0 讨论(0)
  • 2021-02-02 05:40

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

    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 longer than the creation of a literal – whereas the Immutable.Map performs about 50 times worse than the literal.

    0 讨论(0)
  • 2021-02-02 05:42

    Update: Since this answer was originally written, the bug in V8 that caused this issue has been fixed. See the answer by Jan Molak for more info.


    In Google Chrome (so V8, that is), a frozen object iterates 98% slower than a regular 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):

    for(var key in o1);
    

    Test 2 (frozen object):

    for(var key in o2);
    
    0 讨论(0)
  • 2021-02-02 05:45

    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

    0 讨论(0)
  • 2021-02-02 05:46

    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.

    0 讨论(0)
提交回复
热议问题