Макет памяти в Javascript - ориентированный на данные и объектно-ориентированный дизайн

Исходя из фона 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];

Ответ 1

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

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

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

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

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

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

Ответ 2

Ok. Спрятано с некоторыми номерами и тестовыми примерами.

Во-первых, я создал этот тестовый пример 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