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

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

Я делаю игру на основе сетки, и мне нужно хранить несколько частей информации о каждом квадрате. Я знаю, что нельзя обойти несколько уровней массивов / объектов. У меня это уже работает в одном направлении, поэтому прежде чем приступить к изменению огромного количества кода (у меня есть как минимум 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 большими массивами, а не иметь большой двумерный массив со многими очень маленькими объектами.

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

Поиск в 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 мс. Это удивило меня. Но это также означает, что Берги был прав. Это не важно Я был обеспокоен большим количеством существующих объектов, но если 10000 новых объектов занимают менее 10 мс, моя сетка из 400 объектов никогда не должна быть проблемой.

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

2 ответа

Решение

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

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

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

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

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