Выделение памяти для типов JavaScript

Я пытаюсь оптимизировать ад из мобильного приложения, над которым я работаю, и я хотел бы знать, что занимает наименьший объем памяти (я понимаю, что это может отличаться в разных браузерах):

  • указатель на объект
  • логические литералы
  • количество литералов
  • строковые литералы

что теоретически должно занимать наименьшее пространство памяти?

2 ответов


На V8:

Boolean, number, string, null и void 0 литералы принимают константу 4/8 байтов памяти для указателя или немедленного целочисленного значения, встроенного в указатель. Но для них вообще нет выделения кучи, так как строковый литерал будет просто интернализован. Исключением могут быть большие целые числа или двойники, которые упакованы с 4/8 байтами для указателя коробки и 12-16 байтами для коробки. В оптимизированном коде локальные двойники могут оставаться распакованными в регистрах или стеке, или массиве, который всегда содержит исключительно двойники будут хранить их распакованными.

считают мясо сгенерированного кода для:

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

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

как вы можете видеть, указатели на строки жестко и никакого выделения не происходит.

идентификаторы объектов как минимум принимают 12/24 байта для простого объекта, 16/32 байта для массива и 32/72 для функции (+ ~30/60 байт, если объект контекста должен быть выделен). Вы можете уйти только без выделения кучи здесь, Если вы запустите bleeding edge v8, и идентификатор не перейдет в функцию, которая не может быть встроена.

например:

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

резервный массив для значений 1,2,3 будет совместно использоваться как массив копирования при записи всеми массивами, возвращаемыми функцией, но по-прежнему уникальным объектом идентификации для каждого массива, который необходимо выделить. Посмотрите, как сложно сгенерированный код. Поэтому даже при такой оптимизации, если вам не нужны уникальные идентификаторы для массивов, просто возвращайте массив из верхней области будет избегать выделения идентификатора каждый раз, когда функция вызывается:

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

гораздо проще.

если у вас проблемы с памятью с js, не делая ничего, казалось бы, сумасшедшего, вы, безусловно, создаете функции динамически. Поднимите все функции на уровень, где их не нужно воссоздавать. Как вы можете видеть сверху, просто идентичность для функции очень толстая, уже учитывая, что большинство кода может сойти со статики функции, воспользовавшись this.

поэтому, если вы хотите взять что-нибудь из этого, избегайте закрытия non-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;
}

"литерал" означает код (даже если не в сериализации строк), который является более сложным типом и поэтому будет стоить больше места, чем значения.

теоретически логические значения могут занимать наименьшее пространство, так как они вписываются в один бит. Маловероятно, что какой-либо двигатель оптимизирует это. Если вы хотите заставить это, вы можете сделать это вручную и жонглировать типизированными массивами.

, производительность практические вещь, и вы можете только проверять, проверять, проверять это. Как вы уже знаете, нет окончательного кросс-браузерного кросс-версии ответа.