7

私が取り組んでいるモバイルアプリを徹底的に最適化しようとしています.何が最小のメモリフットプリントを占めるのか知りたいです(これはブラウザによって異なる場合があることを認識しています):

  • オブジェクト ポインタ
  • ブール値リテラル
  • 数値リテラル
  • 文字列リテラル

理論的にはどれが最小量のメモリ空間を必要としますか?

4

2 に答える 2

17

V8 の場合:

ブール値、数値、文字列、null、および void 0 のリテラルは、ポインターまたはポインターに埋め込まれた直接の整数値のために、定数 4/8 バイトのメモリを使用します。ただし、文字列リテラルは内部化されるだけなので、これらのヒープ割り当てはまったくありません。例外は、ボックス ポインターの 4/8 バイトとボックスの 12 ~ 16 バイトでボックス化された大きな整数または double である可能性があります。最適化されたコードでは、ローカル double はレジスタまたはスタック内でボックス化されないままになるか、常に double のみを含む配列がボックス化されずに格納されます。

生成されたコードの要点を考えてみましょう:

function weird(d) {
    var a = "foo";
    var b = "bar";
    var c = "quz";

    if( d ) {
        sideEffects(a, b, c);
    }
}

ご覧のとおり、文字列へのポインターはハードコーディングされており、割り当ては行われません。

オブジェクト ID は、プレーン オブジェクトに 12/24 バイト、配列に 16/32 バイト、関数に 32/72 バイト (+ コンテキスト オブジェクトを割り当てる必要がある場合は 30/60 バイト) を必要とします。ブリーディング エッジ v8 を実行し、ID がインライン化できない関数にエスケープされない場合にのみ、ここでヒープ割り当てなしで逃げることができます。

たとえば、次のようになります。

function arr() {
    return [1,2,3]
}

値 1、2、3 のバッキング配列は、関数によって返されるすべての配列によってコピー オン ライト配列として共有されますが、割り当てが必要な各配列の一意の ID オブジェクトは引き続き使用されます。生成されたコードがどれほど複雑かを確認してください。したがって、この最適化を行っても、配列に一意の ID が必要ない場合は、上位スコープから配列を返すだけで、関数が呼び出されるたびに ID の割り当てを回避できます。

var a = [1,2,3];
function arr() {
    return a;
}

はるかに簡単です。

一見おかしなことを何もせずに js でメモリの問題が発生した場合、関数を動的に作成していることは間違いありません。すべての機能を、再作成する必要がないレベルまで上げます。上記からわかるように、ほとんどのコードが を利用して静的関数を回避できることを考えると、関数のアイデンティティだけが非常に太っていますthis

したがって、これから何かを取得したい場合は、目標がパフォーマンスである場合は、非 IIFE クロージャーを避けてください。それらが問題ではないことを示すベンチマークは、壊れたベンチマークです。

8GB を使用している場合、追加のメモリ使用量が問題になることは直感的にわかるかもしれません。C では問題になりませんが、Javascript では、メモリはただそこにあるだけでなく、ガベージ コレクタによってトレースされます。そこにあるメモリとオブジェクトが多いほど、パフォーマンスは低下します。

次のようなものを実行することを検討してください:

var l = 1024 * 1024 * 2
var a = new Array(l);

for( var i = 0, len = a.length; i < len; ++i ) {
    a[i] = function(){};
}

--trace_gc --trace_gc_verbose --print_cumulative_gc_statどれだけの仕事が無駄に行われたかを見てください。

静的関数と比較します。

var l = 1024 * 1024 * 2
var a = new Array(l);
var fn = function(){};

for( var i = 0, len = a.length; i < len; ++i ) {
    a[i] = fn;
}
于 2013-09-24T07:07:16.607 に答える
0

"Literal" means code (even if not in string serialisation), which is a more complex type and will therefore cost more space than values.

Theoretically, boolean values could take the least amount of space since they fit in a single bit. It's unlikely though that any engine does optimize this. If you want to force this, you can do it manually and juggle around with typed arrays.

However, performance is a practical thing, and you can only test, test, test it. As you already know, there is no definitive cross-browser cross-version answer.

于 2013-09-23T23:47:22.940 に答える