Development Tip

JavaScript 객체를 "잠금"하면 성능상의 이점이 있습니까?

yourdevel 2020. 11. 21. 09:09
반응형

JavaScript 객체를 "잠금"하면 성능상의 이점이 있습니까?


JavaScript 1.8.5 (ECMAScript 5)에는 전달 된 객체의 향후 수정방지 하는 몇 가지 흥미로운 메서드가 추가되어 있습니다 .

아마도 이것의 요점은 실수를 포착하는 것입니다. 특정 지점 이후에 개체를 수정하고 싶지 않다는 것을 알고 있다면 나중에 실수로 수정하려고하면 오류가 발생하도록 잠글 수 있습니다. (당신이 그렇게 "use strict";했다는 것을 제공합니다 .)

내 질문 : V8과 같은 최신 JS 엔진에서 위의 방법을 사용하여 객체를 잠글 때 성능상의 이점 (예 : 빠른 속성 조회, 메모리 사용량 감소)이 있습니까?

( John Resig의 멋진 설명 도 참조하십시오 . 성능은 언급하지 않습니다.)


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

성능 테스트 ( 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);

업데이트 17.09.2019 : Chrome 76.0.3809 (64 비트) 에서 성능 차이가 없습니다.

업데이트 03.05.2018 : Chrome 66.0.3359 (64 비트) 에서 성능 차이 없음

업데이트 06.03.2017 : Chrome 56.0.2924 (64 비트) 에서 성능 차이가 없습니다.

업데이트 13.12.2015 : Chrome 47.0.2526.80 (64 비트) 에서 성능 차이가 없습니다.


Chrome 34에서는 고정 된 개체가 @pimvdb의 테스트 사례에서 고정되지 않은 개체보다 약간 더 잘 수행됩니다 (아래 결과). 그러나 그 차이는 성능상의 이점을 위해이 기술을 사용하는 것을 정당화하기에 충분하지 않은 것 같습니다.

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

@kangax의 테스트 케이스를 실행하면 두 버전의 객체가 거의 동일하게 수행된다는 것을 알 수 있습니다.

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

Google Chrome (즉, V8)에서 고정 된 개체 는 일반 개체보다 98 % 느리게 반복 됩니다.

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

EDIT:

Since this answer was originally written, the bug in V8 that caused this issue has been fixed. See the answer by Jan Molak above for mor


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.


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


As per the Google Code issue:

The performance difference is due to the backing store data structure. For few properties, the object descriptor describes where the properties are stored, in a property array. If the number of properties grow, we eventually switch to a dictionary for backing store, which is less performant, but more flexible. When we freeze an object, what is being done is that all properties are set to unconfigurable and unwritable. Storing those attributes is only possible in a dictionary backing store, so we switch to that.

EDIT: More work has been done towards optimising this and the difference between normal objects and frozen objects has been decreased to about 20%. Sealed objects still take twice as long to iterate but work is being don on this.


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.


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.

참고URL : https://stackoverflow.com/questions/8435080/any-performance-benefit-to-locking-down-javascript-objects

반응형