Производительность JavaScript: несколько переменных или один объект?
Это простой вопрос производительности, который помогает мне понять механизм javascript.
для этого мне было интересно, что быстрее: объявление нескольких переменных для определенных значений или использование одного объекта, содержащего несколько значений.
Пример:
var x = 15;
var y = 300;
против.
var sizes = { x: 15, y: 300 };
Это просто очень простой пример, конечно, может отличаться в реальном проекте.
это даже имеет значение?
Ответы
Ответ 1
Полный ответ на этот вопрос будет очень долгим. Поэтому я попытаюсь объяснить только некоторые вещи. Во-первых, возможно, самый важный факт, даже если вы объявляете переменную с var
, это зависит от того, где вы это делаете. В глобальном масштабе вы неявно также записываете эту переменную в объект, большинство браузеров называют ее window
. Так, например,
// global scope
var x = 15;
console.log( window.x ); // 15
Если мы делаем то же самое в контексте функции, вещи меняются. В контексте функции мы будем записывать это имя переменной в его так называемый "Объект активации". То есть, внутренний объект, который движок js обрабатывает для вас. Здесь хранятся все формальные параметры, декларации функций и переменные.
Теперь, чтобы ответить на ваш реальный вопрос: в контексте функции всегда есть самый быстрый доступ к переменным, объявленным с помощью var
. Это снова не обязательно верно, если мы находимся в глобальном контексте. Глобальный объект очень огромен и не очень быстрый доступ к чему-либо внутри.
Если мы храним вещи внутри объекта, все еще очень быстро, но не так быстро, как переменные, объявленные var
. Особенно увеличивается время доступа. Но, тем не менее, речь идет о микро и наносекундах здесь (в современных реализациях браузера). Старые браузеры, особенно IE6 + 7, имеют огромные штрафы за производительность при доступе к свойствам объекта.
Если вы действительно заинтересованы в таких вещах, я рекомендую книгу " High Performance Javascript" Николая К. Закаса. Он измерил множество различных методов доступа и хранения данных в ECMAscript для вас.
Опять же, различия в производительности для поиска объектов и переменных, объявленных var
, почти не могут быть измерены в современных браузерах. Старые браузеры, такие как FF3 или IE6, демонстрируют фундаментальную медленную производительность для поиска объектов/доступа.
Ответ 2
Вы определенно микро-оптимизируете. Я бы не стал беспокоиться об этом, пока не появится очевидное узкое место производительности, и вы сузили проблему с использованием нескольких vars против объекта со свойствами.
Логическое мышление об этом с использованием объектного подхода требует трех созданий переменных: одного для объекта и одного для каждого свойства объекта, vs 2 для простого объявления переменных. Поэтому наличие объекта будет иметь более высокий подход к памяти. Однако, вероятно, более эффективно передавать объект методу, чем n > 1 переменных, поскольку вам нужно всего лишь скопировать 1 значение (javascript - это значение по умолчанию). Это также имеет последствия для отслеживания лексического охвата объектов; то есть передача меньше вещей методам будет использовать меньше памяти.
однако я сомневаюсь, что различия в производительности будут даже поддаваться количественной оценке любым профилировщиком.
Ответ 3
Теория или вопросы типа "Что вы... хм.. делаете, чувак?", конечно, могут появиться здесь в качестве ответов. Но я не думаю, что это хороший подход.
Я только что создал два стенда:
Это показывает, например, что в 07/2017 в браузерах Chromium ( Vivaldi, Opera, Google Chrome и др.) для достижения максимальной производительности предпочтительнее использовать var. Он работает примерно на 25% быстрее для чтения значений и на 10% быстрее для записи.
В Node.js есть примерно одинаковые результаты - из-за того же JS-движка.
В Opera Presto ( 12.18) есть аналогичные процентные результаты теста, как в браузерах на основе хрома.
В (современном) Firefox есть и другая и странная картина. Чтение глобальной области var примерно такое же, как чтение свойства объекта, а запись глобальной области var значительно медленнее, чем запись obj.prop(примерно в два раза медленнее). Это похоже на ошибку.
Для тестирования в IE/Edge или любых других случаях, вы можете.
- Обычный случай, http://jsben.ch/5UvSZ для локальной функциональной области
В браузерах на основе хрома и Mozilla Firefox вы можете видеть огромное доминирование простой производительности var в зависимости от доступа к объекту. Локальные простые переменные несколько раз (!) Быстрее, чем дело с объектами.
Итак,
если вам нужно максимизировать критическую производительность JavaScript-кода:
-
в браузере - вы можете сделать разные оптимизации для нескольких браузеров. Я не рекомендую! Или вы можете выбрать "любимый" браузер, оптимизировать свой код для него и не видеть, что зависания происходят в других. Не очень хорошо, но есть способ.
-
в браузере, опять же - вам действительно нужно оптимизировать этот путь? Может быть, что-то не так в вашей логике алгоритма/кода?
-
в высокопроизводительном Node.js модуле (или других высокоточных вычислениях) - ну, попробуйте минимизировать объекты "точек", с минимальным повреждением качества/удобочитаемости курса - используйте var
.
Безопасный трюк оптимизации для любого случая - если у вас слишком много операций с obj.subobj.*
, вы можете сделать var subobj = obj.subobj;
и работать с subobj.*
. Это может улучшить читаемость.
В любом случае, подумайте, что вам нужно, и сделайте и сделайте реальные bechmarks вашего высокопроизводительного кода.