2

すべての dart ファイルのコンパイルされた JavaScript の先頭には、この奇妙なリストがあります。

function dart() {
  this.x = 0;
  delete this.x;
}
var A = new dart;
var B = new dart;
var C = new dart;
var D = new dart;
var E = new dart;
var F = new dart;
... etc etc ...
var Z = new dart;

残りのコードをスキャンして .A (またはその他の文字) を探しましたが、うまくいきませんでした。これは正確にはどのような目的に役立ちますか? 最終的な結果として、dart() 関数/コンストラクターの AZ インスタンスは空のクラス オブジェクトになりますが、何の役に立つのでしょうか?

私が見つけたように正規表現を使用する/[A-Z]{1}\./と、いくつかの文字インスタンスがプロパティで装飾されており、27 文字すべてがこの関数を介して実行されます。

function convertToFastObject(properties) {
  function MyClass() {
  }
  MyClass.prototype = properties;
  new MyClass();
  return properties;
}
;
A = convertToFastObject(A);
B = convertToFastObject(B);
C = convertToFastObject(C);
... etc etc ...
Z = convertToFastObject(Z);

それは私をさらに混乱させました。その行はSomeObject = convertToFastObject(SomeObject);変更なしのように見えるようです。

編集/更新: convertToFastObject とその前身の dart() クラスの説明が見つかりました -なぜ convertToFastObject 関数で高速になるのですか? 最適化のトリックです。なぜ AZ のインスタンスのリストなのかという疑問が残りますが、これは別の最適化のトリックなのか、それともコードのハッシュ テーブルのようなものなのでしょうか?

4

2 に答える 2

5

AZ クラスは、さまざまな Dart ライブラリ用に予約されたグローバルです。ソースでわかるように、これらの少数は特定のライブラリに使用されます。

static const reservedGlobalObjectNames = const <String>[
    "A",
    "B",
    "C", // Global object for *C*onstants.
    "D",
    "E",
    "F",
    "G",
    "H", // Global object for internal (*H*elper) libraries.
    // I is used for used for the Isolate function.
    "J", // Global object for the interceptor library.
    "K",
    "L",
    "M",
    "N",
    "O",
    "P", // Global object for other *P*latform libraries.
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W", // Global object for *W*eb libraries (dart:html).
    "X",
    "Y",
    "Z",
];

残りはすべて、 globalObjectForメソッドで示されるように分離に使用されているようで、分離を使用する dart2js コンパイル コードの結果を表示します。

于 2014-12-24T03:59:46.530 に答える
3

これらのオブジェクトには、Dart プログラムで定義されたすべての静的 (グローバル、クラスなど) が含まれます (ツリー シェイクアウェイされていません)。それらを「グローバル オブジェクト」と呼びます。

ここにはいくつかの歴史があります。最初は、JS の最上位にあるグローバル オブジェクトが 1 つしかありませんでした。私たちは、JavaScript のグローバル名前空間を汚染したくありませんでした (そして今でも汚染したくありません)。プログラムを無名関数にラップしたのは、プログラムの速度が低下したからではありません。

事態は進化しました... JavaScript エンジンはネストされたスコープで高速になり、コードを無名関数に移動しました。これにより、より多くの「トップレベル」(関数にラップされた) オブジェクトに切り替えることが可能になりました。また、JS エンジンは、あまりにも多くのプロパティを含むオブジェクトには非常に適していないことも発見しました。結果として、1 つのグローバル オブジェクトをより小さな断片に分割し、コンパイルされた静的/クラスを異なるグローバル オブジェクトに配布します。Dart クラスが最終的にどこに到達するかは、内部ライブラリの事前定義されたマップに基づいており、他のライブラリのライブラリ名に基づいています。

特定の数 (「A」の場合は 1000、「B」の場合は 1000 など) まで実行するだけではありません。これは、小さな変更を行うと JS 出力が大幅に変化する可能性があるためです。

これらのオブジェクトを取り除くことができるようになりましたが、その必要性はまだ見ていません。JS エンジンは、オブジェクト アクセスの最適化に非常に優れています。私はそれをテストしていませんが、同じオブジェクトの 2 つの関数を使用することは、おそらく 2 つのローカル変数を使用するよりも速いか、同じくらい速いと思います。

于 2014-12-24T11:44:54.977 に答える