web-dev-qa-db-ja.com

JavaScriptオブジェクトを「ロックダウン」することによるパフォーマンス上の利点はありますか?

JavaScript 1.8.5(ECMAScript 5)は、渡されたオブジェクトの将来の変更を防ぐであるいくつかの興味深いメソッドを追加します。

おそらくこれらの主なポイントは間違いを見つけることです:特定のポイントの後でオブジェクトを変更したくないことがわかっている場合は、後でそれを変更しようとするとエラーがスローされるように、オブジェクトをロックダウンできます。 (_"use strict";が完了したことを提供します。)

私の質問: V8などの最新のJSエンジンでは、上記の方法を使用してオブジェクトをロックダウンすることで、パフォーマンスの利点(たとえば、プロパティルックアップの高速化、メモリフットプリントの削減)はありますか?

(参照 John Resigの素晴らしい説明 –ただし、パフォーマンスについては言及していません。)

70
callum

少なくとも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

パフォーマンステスト( 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);

アップデート03.05.2018:Chrome66.0.3359(64 -ビット)

アップデート06.03.2017:Chrome56.0.2924(64 -ビット)

アップデート13.12.2015:Chrome47.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
72
Jan Molak

Google Chrome(つまりV8、つまり))では、フリーズされたオブジェクトは反復します98%遅い通常のオブジェクトよりも遅くなります。

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

Test name*              ops/sec

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

おそらくこれは、これらの関数が比較的新しく、おそらくまだ最適化されていないためです(しかし、それは私の推測ですが、正直に理由はわかりません)。

とにかく、それは明らかに意味をなさないので、パフォーマンス上の利点のために実際に使用することはお勧めしません。


*テストのコードは次のとおりです。

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

Object.freeze(o2);

テスト1(非凍結オブジェクト):

for(var key in o1);

テスト2(凍結オブジェクト):

for(var key in o2);

編集:

この回答はもともと書かれていたため、 この問題の原因となったV8のバグ が修正されました。詳細については、上記の Jan Molak の回答を参照してください

14
pimvdb

理論的には、オブジェクトを凍結すると、オブジェクトの形状についてより強力な保証を行うことができます。

これは、VMがメモリサイズを圧縮できることを意味します。

これは、VMがプロトタイプチェーンのプロパティルックアップを最適化できることを意味します。

これは、オブジェクトが変更できないため、ライブ参照がライブでなくなったということです。

実際には、JavaScriptエンジンはこれらの積極的な最適化をまだ行いません。

11
Raynos

V8は2013年6月20日の時点でObject.freezeを最適化しています。また、2014年12月10日の時点でObject.sealとObject.preventExtensionsを最適化しています。問題 https://code.google.com/p/chromium/issues/を参照してください。詳細?id = 11596

5
llambda

Google Codeの問題 に従って:

パフォーマンスの違いは、バッキングストアのデータ構造によるものです。一部のプロパティの場合、オブジェクト記述子は、プロパティがプロパティ配列に格納される場所を記述します。プロパティの数が増えると、最終的にはバッキングストア用のディクショナリに切り替えます。これは、パフォーマンスは低くなりますが、柔軟性が高くなります。オブジェクトをフリーズすると、すべてのプロパティが構成および書き込み不可に設定されます。これらの属性の保存は、辞書バッキングストアでのみ可能であるため、それに切り替えます。

EDIT:これを最適化するためにより多くの作業が行われ、通常のオブジェクトとフリーズされたオブジェクトの違いが約20%に減少しました。シールされたオブジェクトは、反復するのに2倍の時間がかかりますが、これについては作業が行われていません。

2
Bardi Harborow

オブジェクトcreationのパフォーマンスに興味がある場合(リテラルvs凍結vs密封vs Immutable.Map )、それを確認するために jsPerfでのテスト を作成しました。

これまでのところ、Chrome 41およびFirefox 37)でテストする機会しかありませんでした。どちらのブラウザでも、凍結またはシールされたオブジェクトの作成にはリテラルの作成より3倍長いImmutable.Mapは、リテラルより約50倍パフォーマンスが悪い。

0
tomekwi

量産コードでこれらのメソッドについて私が見る唯一の理由は、整合性の目的で、オブジェクトをシールまたは凍結できることです。

たとえば、私は小さなライブラリを作成します。これは非常にうまく機能し、オブジェクトに一連のメソッドを提供しますが、私のプロパティやメソッドを変更したり上書きしたりしたくありません。私はあなたがそれをするのを防ぐことができると言っているわけではありませんが、あなたが偶然にそれをするのを防ぐように試みることができます。

また、これらのメソッドは、元のオブジェクトを返すだけで、それらについて知らない環境で簡単に「シム」できます。もちろん、その場合は効果がありません。

これを実行する理由に関連するパフォーマンスはありません。

0
jAndy