Эффективность: объекты внутри массивов или массивы внутри объектов?

Учитывая одинаковое количество слоев массива/объекта, каждый индекс указывает на одни и те же вещи, каков наилучший порядок вложения массивов и объектов?

Я делаю игру на основе сетки, и мне нужно хранить несколько фрагментов информации о каждом квадрате. Я знаю, что невозможно обойти несколько уровней массивов/объектов. У меня это уже работает одним способом, поэтому, прежде чем я начну изменять огромное количество кода (у меня есть как минимум 5 функций с тяжелым оператором switch внутри каждой (чтобы выбрать слой, с которым мы работаем), и может быть, 10 других, которые мне также придется изменить вместе с функцией инициализации), я хотел бы знать, действительно ли это изменение соответствует лучшим практикам.

В настоящее время у меня это выглядит так: Game.grid.map[x][y][layer][direction], поэтому карта с обычным 2D-массивом, и каждый элемент является объектом, содержащим свойства "V", "S", "M" и "G" , каждый из которых содержит массив. (металл, кремний, ворота и переходные отверстия)

Я подумывал о переходе на Game.grid.map[layer][x][y][direction]. Мне пришлось бы немного изменить структуру (например, где у меня есть var base = this.map[x][y];, а затем использовать base[layer][dir]. Но я мог бы легко внести это изменение и использовать переменные baseM, baseG и baseS. Просто утомительно менять Я хотел бы знать, будет ли более эффективно иметь 1 объект с 5 большими массивами, чем иметь большой 2D-массив со многими очень маленькими объектами.

Я где-то читал, что в чистых массивах это зависит от того, как часто индекс меняется на каждом уровне, а внешние уровни меняются медленнее. По этому есть смысл его менять. Я склонен иметь дело с металлом сразу, переходными отверстиями сразу, кремнием и гейтами вместе.

Поиск в Google привел меня к следующему QA: Самый быстрый способ чтения /хранить много многомерных данных? (Java), но это касается только чистых массивов, а не смеси объектов и массивов.

===Изменить===

1) Так что да, я пропустил, что QA, который я нашел, был java вместо javaScript.

2) Я немного изменил их тест.

var arr = [];
for (int x=0; x<100; x++){
    arr[x] = [];
    for (int y=0; y<100; y++){
        arr[x][y] = [];
        for (int z=0; z<100; z++){
             arr[x][y][z] = 1;
        }
    }
}

Это заняло около 10 мс. (измерено путем вставки функции в консоль и вычитания этой метки времени из «неопределенной» метки времени.) Между созданием верхнего уровня как объекта и созданием нижнего уровня как группы объектов также было 10 мс. Создание всех объектов уровней заняло 9 мс. Это меня удивило. Но это также означает, что Берги был прав. Это не имеет значения. Меня беспокоило огромное количество существующих объектов, но если 10 000 новых объектов занимают менее 10 мс, моя сетка из 400 объектов никогда не должна быть проблемой.

Так что на самом деле единственное изменение в эффективности, которое можно найти, заключается в том, сколько времени вам потребуется для чтения/записи кода, помеченного тем или иным способом. И для меня определенно проще избежать параллельных массивов на этом. (Я не знал, что этот вопрос будет о микрооптимизации.) Спасибо всем, кто ответил.


person RoboticRenaissance    schedule 15.12.2015    source источник
comment
Я бы подождал, пока вы не реализуете самые эффективные алгоритмы высокого уровня, которые вы можете найти, прежде чем даже думать об этой проблеме. Подобные микрооптимизации — пустая трата времени, пока вы не убедитесь, что неправильный выбор алгоритма не является источником 90% проблем с производительностью.   -  person Pointy    schedule 15.12.2015
comment
Кроме того, в любом случае поиск свойств в JavaScript, как правило, сильно оптимизирован. Это фундаментальная операция во всем коде JavaScript.   -  person Pointy    schedule 15.12.2015
comment
Кроме того, ничто о низкоуровневой эффективности времени выполнения в Java не будет иметь ничего общего с JavaScript.   -  person Pointy    schedule 15.12.2015
comment
Это последнее, почему этот вопрос должен был быть задан. В JavaScript нет ничего об этом, что я могу легко найти в Google. Другие QA, которых я нашел, были людьми, которые вообще не знали, как писать объекты.   -  person RoboticRenaissance    schedule 15.12.2015
comment
Зачем вам двумерный массив? Если вы работаете с сеткой, вы можете использовать одномерный массив и просто отслеживать расположение строк. Таким образом, у вас есть один индекс для каждого квадрата сетки, а математика для обработки адресации не только проста, но и выполняется очень быстро.   -  person Robusto    schedule 15.12.2015
comment
Robusto: Это читабельность. Чтобы иметь какой-то смысл в моих многочисленных функциях, мне пришлось бы добавить еще одну функцию для возврата индекса квадрата сетки. Конечно, у меня уже есть отдельная функция для поиска соседних квадратов, потому что она используется в двух разных функциях. Если бы объекты оказались на самом деле медленнее, я мог бы использовать эту технику для выравнивания свойств каждого квадрата (максимум 18 элементов на квадрат).   -  person RoboticRenaissance    schedule 15.12.2015


Ответы (2)


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

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

person Bergi    schedule 15.12.2015

О скольких объектах вы говорите? Как упоминается в @Bergi answer, есть еще МНОГО оптимизации, прежде чем вы пойдете по этому пути. . Технически массивы могут быть немного быстрее для доступа через индекс во время итерации благодаря объектам через свойства, даже тогда это зависит от реализации JS-движка, который может сильно различаться в сложных ситуациях, таких как массивы массивов.

Кроме того, в зависимости от количества объектов, вы можете столкнуться с ограничениями памяти. В конце концов, протестируйте браузеры, поддержку которых вы больше всего хотите. это все, к чему это может привести. Избегайте зацикливания слишком большого количества элементов одновременно (как только вы превысите 10 000 или около того, это может икать, более миллиона, и у вас могут возникнуть проблемы).

person Tracker1    schedule 15.12.2015
comment
Что вы подразумеваете под массивы могут быть немного быстрее для итерации? Тогда что? И нет, это никак не связано с тем, заранее заявлен размер или нет. - person Bergi; 15.12.2015