Расположение памяти в Javascript - ориентированный на данные против объектно-ориентированного дизайна

Исходя из опыта C/C++, расположение объектов в памяти с точки зрения уменьшения потерь в кеше - это то, что особенно важно при работе на консолях. Проектирование, ориентированное на данные, часто предпочитается объектно-ориентированному проектированию, чтобы помочь связанным объектам находиться близко друг к другу в памяти (особенно в критических областях производительности).

Недавно я занимался разработкой Javascript, и мне интересно, каково общее согласие в сообществе Javascript.

Из-за моего ограниченного опыта работы с Javascript я часто удивлялся, увидев совершенно неожиданные результаты при профилировании. Структура внутренней памяти и реализация объектов / структур Javascript настолько сильно различаются от браузера к браузеру, что мне интересно, стоит ли пытаться оптимизировать их.

Я создал простой тестовый пример ( http://jsperf.com/object-vs-data) для jsPerf, чтобы сравнить производительность двух методов, и хотя он показывает повышение производительности в Chrome, в Safari не наблюдается заметного ускорения.

В Javascript, я должен даже заботиться о расположении объектов в памяти? Или это скорее "реализовать его одним способом, а затем оптимизировать, если необходимо"?

Этот второй вариант кажется расточительным (с точки зрения времени разработки), особенно если есть какое-то хорошее руководство.

Благодаря ~

Дополнительная информация: Это в основном то, как я бы реализовал два подхода в Javascript. Тестовый пример jsPerf, описанный выше, реализован следующим образом.

var objectOriented = [
    { foo: 1, bar: 2 },
    { foo: 3, bar: 4 }
];

var dataOriented = {
    foos: [1, 3],
    bars: [2, 4]
};

// Object-oriented access:
var a = objectOriented[0].bar;

// Data-oriented access:
var b = dataOriented.bars[0];

2 ответа

Решение

Вы работаете с фундаментальным предположением, что объекты в Javascript работают так же, как в C++. Они не

В C++ основная цель типа состоит в том, чтобы действовать как "линза" над частью памяти. Компоновка класса напрямую определяет содержимое памяти, которую описывает объект, четко определенным образом. Для массивов C/C++ требуется линейная непрерывная компоновка однородных типов.

В JavaScript объект представляет собой набор пар имя / значение. Массив - это просто объект со специальным свойством length. Обратите внимание, что здесь нет описания или определения расположения памяти. Ничто не мешает интерпретатору Javascript реализовать массивы как хеш-таблицу, а не как линейный кусок памяти; на самом деле, я уверен, что они являются реализациями JS, которые делают именно это.

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

Кроме того, массивы JavaScript неоднородны, а не однородны. То есть, предполагая, что он был размещен в смежной памяти, ваш эквивалентный тип в C будет JSObject **, а не int ** (или float ** или что-то еще). Массив JS - это коллекция ссылок на данные, хранящиеся в другом месте, поэтому, даже если ссылки были в вашей строке кэша, ваши данные не будут.

Итак, в заключение - такое мышление не принесет вам ничего, кроме боли. JavaScript - это язык более высокого уровня, чем C++, и отчасти он отказывается от привычного для вас элемента управления. Такая низкоуровневая оптимизация, если возможно, будет выполняться переводчиком. Сконцентрируйтесь на написании кода с эффективными алгоритмами, которые естественным образом выражают ваше решение; это достаточно сложно, как есть.:-)

Хорошо. Поиграл с некоторыми цифрами и тестами.

Сначала я создал этот тестовый пример http://jsperf.com/object-vs-array-creation-for-so В этом случае создание Object это намного быстрее, чем создание Array

Во-вторых, я создал этот тестовый пример http://jsperf.com/accessing-speed В этом между ними почти не было разницы..

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

Но..

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

Тестирование в Chrome 36.0.1985.125 на Windows NT 6.3

Другие вопросы по тегам