Производительность 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 или любых других случаях, вы можете.


  1. Обычный случай, http://jsben.ch/5UvSZ для локальной функциональной области

В браузерах на основе хрома и Mozilla Firefox вы можете видеть огромное доминирование простой производительности var в зависимости от доступа к объекту. Локальные простые переменные несколько раз (!) Быстрее, чем дело с объектами.


Итак,

если вам нужно максимизировать критическую производительность JavaScript-кода:

  • в браузере - вы можете сделать разные оптимизации для нескольких браузеров. Я не рекомендую! Или вы можете выбрать "любимый" браузер, оптимизировать свой код для него и не видеть, что зависания происходят в других. Не очень хорошо, но есть способ.

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

  • в высокопроизводительном Node.js модуле (или других высокоточных вычислениях) - ну, попробуйте минимизировать объекты "точек", с минимальным повреждением качества/удобочитаемости курса - используйте var.

Безопасный трюк оптимизации для любого случая - если у вас слишком много операций с obj.subobj.*, вы можете сделать var subobj = obj.subobj; и работать с subobj.*. Это может улучшить читаемость.

В любом случае, подумайте, что вам нужно, и сделайте и сделайте реальные bechmarks вашего высокопроизводительного кода.