Оператор var javascript и производительность

Вариант 1: несколько переменных без назначения

function MyFunction() {

  var a = null;
  var b = null;
  ....
  var z = null;

  a = SomeValue;
  b = SomeValue2;
  ....
}

Вариант 2: один оператор var, без присваивания

function MyFunction() {

  var a, b ..., z;

  a = SomeValue;
  b = SomeValue2;
  ....
}

Вариант 3: несколько операторов var с присваиванием

function MyFunction() {

  var a = SomeValue;
  var b = SomeValue2;
  ....
  var z = SomeValue26;
}

Есть ли какое-либо преимущество в производительности при использовании определенного параметра? Верно ли это для обоих назначений примитивных типов AND для назначений ссылок на объекты?

Спасибо за ваш вклад.


person frenchie    schedule 12.03.2012    source источник
comment
я не знаю о различиях в производительности, но стилистически я бы выбрал вариант 3.   -  person c0deNinja    schedule 12.03.2012
comment
Есть так много вещей, которые могут еще больше повлиять на вашу производительность, поэтому вам не стоит беспокоиться об этом... Просто делайте то, что вам легче читать, так как это не повлияет на производительность. Кроме того, это может варьироваться в зависимости от того, какой JS-движок вы используете.   -  person Ortiga    schedule 12.03.2012
comment
Обратите внимание, что вариант 1 на самом деле не то, что вы называете. На самом деле есть два присвоения: одно, когда вы объявляете переменную и присваиваете ей null, а затем еще раз, когда вы назначаете SomeValue.   -  person josh3736    schedule 12.03.2012
comment
Присвоение значения при объявлении происходит значительно быстрее (см. этот jsPerf). заявления или нет, не имеет большого значения.   -  person Chad    schedule 12.03.2012


Ответы (7)


«преждевременная оптимизация — корень всех зол»

Я не думаю, что любой из этих вариантов будет значительно изменять производительность.
(ИМО) Третий вариант является наиболее читабельным и наиболее близким к динамическому распределению памяти, например C# и т. д.'. Но это мое скромное мнение. Выберите то, что вам больше нравится.

Если это вас действительно беспокоит и вы не можете уснуть без ответа, проверьте это с помощью jsPerf. .


@Chad сделал jsPerf, чтобы вы могли спать спокойно сегодня ночью...

person gdoron is supporting Monica    schedule 12.03.2012
comment
Присвоение значения при объявлении может быть почти на 60% быстрее, чем объявление с последующим присвоением (jsPerf) - person Chad; 12.03.2012
comment
@Чад. Добавлен ваш jsPerf. Обратите внимание, что в chrome все результаты совершенно одинаковы! - person gdoron is supporting Monica; 12.03.2012
comment
@Chad Я провел этот тест годом позже в Chrome 29, FF 23 и IE 10.0 и также увидел, что все результаты находятся в пределах погрешности (то есть точно такие же). - person T Nguyen; 08.09.2013
comment
Да, была небольшая разница в FF до v20. После этого во всех браузерах скорость одинаковая. Нет разницы! - person Chad; 09.09.2013
comment
Исходный код должен быть читабельным, пусть выбранный вами инструмент минификатора/компилятора сделает грязную работу. - person Jens; 05.03.2014
comment
голосую за дельный совет преждевременная оптимизация — корень всех зол - person Prakash K; 21.07.2017

Чтобы понять производительность, вы должны сначала понять подъем. Возьмем следующий код:

var x = 1;

function bar(val) {
    var returnVal = val * 2;

    return returnVal;
}

function foo(val) {
    var returnVal = 10;

    returnVal *= bar(val);

    return returnVal;
}

var y = foo(x);

console.log(y); // 20

Подъем в основном означает, что интерпретатор JavaScript «поднимет» объявление переменной наверх своей области. Чтобы этот пример выглядел примерно так:

var x, y;

x = 1;

function bar(val) {
    var returnVal;

    returnVal = val * 2;

    return returnVal;
}

function foo(val) {
    var returnVal;

    returnVal = 10;
    returnVal *= bar(val);

    return returnVal;
}

y = foo(x);

console.log(y); // 20

Итак, в приведенных вами примерах варианты 2 и 3 будут в основном делать то же самое. Поскольку интерпретатор переместит эти объявления наверх. В этот момент это решение предпочтения. Многие люди избегают делать что-то вроде var x, y, z;, говоря, что это опасно. Я, лично, делаю это. В какой бы области я ни находился, я буду объявлять все переменные вверху, а затем использовать их ниже. Но в любом случае работает.

Теперь ваш первый пример наименее эффективен. После подъема это будет выглядеть так:

function MyFunction() {
    var a, b, ... z;

    a = null;
    b = null;
    ...
    z = null;

    a = someValue;
    b = someValue2;
    ...
    z = someValueN;
}

В основном это приводит к установке переменных дважды.

person Marshall    schedule 12.03.2012

В Chrome время выполнения одинаково.

Единственным реальным соображением здесь является оптимизация сетевой передачи.

Сравните var a=1;var b=2;...;var z=9; и var a=1,b=2,...,z=9;

Если вы поместите ;var  перед каждым идентификатором, это будет 5 байтов (при условии однобайтовой кодировки символов) по сравнению с 1 байтом для ,. Таким образом, объявив 26 переменных, можно сэкономить 100 байт, написав var  один раз и перечислив идентификаторы через запятую.

Конечно, это не огромная экономия, но каждый байт помогает, когда дело доходит до передачи битов по сети. Не о чем сильно беспокоиться, но если вы обнаружите, что объявляете несколько переменных в одной и той же области, использование списка объявлений переменных — это простой способ сократить ваш JS-файл на несколько байтов.

person josh3736    schedule 12.03.2012

Это похоже на преждевременную оптимизацию, корень всех зол.

Сколько раз он будет выполняться? Какую часть всей программы это займет?

person Ayman    schedule 12.03.2012

Я отвечу на ваш вопрос о производительности несколькими вопросами:

  1. Вы заметили проблему с производительностью?
  2. Вы определили, что ваш оператор var был узким местом?
  3. Вы тестировали каждую версию?

Я собираюсь предположить, что ответ на все эти вопросы был нет.

Ни один из вариантов не должен иметь существенного значения, хотя единственный способ узнать наверняка — запустить их и протестировать. Поскольку JavaScript является асинхронным языком клиентской части, вам придется выполнить очень огромный код, чтобы операторы var стали каким-либо узким местом.


В конце концов, если вы решаете, какую версию использовать, я бы рекомендовал использовать один оператор var без присваивания:

function () {
    var a,
        b,
        c,
        foo,
        bar,
        fizz,
        buzz;
    a = 1;
    ...
    b = 3;
}

Причина этого в том, что именно так код будет выполняться из-за подъема переменных. Затем я могу переместить оператор инициализации туда, где переменная используется впервые, например, в цикле for:

function foo(arr) {
    var i,
        l;
    ...
    for (i = 0, l = arr.length; i < l; i++) {
        doStuff(arr[i]);
    }
    ...
}
person zzzzBov    schedule 12.03.2012
comment
JavaScript полностью синхронный, а не асинхронный. - person Wk_of_Angmar; 09.04.2013
comment
@Wk_of_Angmar, вы упустили суть. JavaScript при выполнении является синхронным, однако большая часть кода выполняется асинхронно. Подавляющее большинство времени подавляющее большинство JavaScript просто ждет, пока браузер сообщит ему, что что-то произошло, просто для того, чтобы он мог выполниться за пару сотых миллисекунды. - person zzzzBov; 09.04.2013

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

Тем не менее, есть некоторые стилистические рекомендации, которым вы должны следовать, и или когда они вам понадобятся">этот ответ хорошо объясняет их. Имейте в виду, что этот ответ не зависит от технологии и может вообще не относиться к JavaScript.

person Cᴏʀʏ    schedule 12.03.2012

Просто держитесь подальше от варианта 1, если это возможно, нет необходимости делать два назначения.

Даже переменные, объявленные внутри цикла for или другого составного оператора/блока, будут доступны за пределами содержащего его блока.

Вы также можете сделать:

function MyFunction() {

  var a = SomeValue, b = SomeVavlue2;

}
person dave    schedule 12.03.2012