Search code examples
javascriptecmascript-5javascript-1.8

Any performance benefit to "locking down" JavaScript objects?


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

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.)


Solution

  • 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