Что быстрее массив или объект?

Пишу чат на nodejs. Храню данные в виде объекта.
const companies = {
    2: {
        id: 2,
        company_name: 'My company',
        users: {
            1: {
                id: 1,
                name: 'John',
                messages: [...]
            }
        }
    }
}


Примерно так. Храню я данные в объекте, а не в массиве по двум причинам:
1) Так удобнее обращаться. Например, я могу прямо в разметке (я использую Vue) вывести имя пользователя.
<span>{{ companies[company_id].users[user_id].name }}</span>

2) Так быстрее, потому что мы сразу обращаемся к конкретному свойству.

Затем я решил посмотреть на разницу. Написал небольшой скрипт, который запустил в браузере.
Суть скрипта в том, что он миллион раз ищет данные в массиве и в объекте. Упрощенно он выглядит так:
const objResult = obj[key];
//VS
const arrResult = arr.find(el => el.id === key);

К моему ужасу поиск по массиву на порядки быстрее.
Наверное браузер что-нибудь кэширует и вообще в браузере такие замеры проводить неправильно. Тогда я пошел в интернет и в первом же вопросе на stackoverflow пишут "Arrays are mostly faster than objects".
Я еще смотрел в разных источниках, мнения разнятся.

Объясните, пожалуйста, почему такой вопрос вообще обсуждается и имеет место быть? Ведь обращение к объекту по ключу - это вообще не поиск. Скрипт сразу знает и сразу получает данные. В массиве напротив - это всегда перебор всего массива каждый раз.
  • Вопрос задан
  • 2550 просмотров
Решения вопроса 3
Мне это напомнило историю, когда некий докладчик сравнил поиск в Яндексе и прямое указание сайта в адресной строке. Типа, когда он пишет адрес сайта, то сразу переходит на него, и якобы поиск не включается. Однако даже при прямом указании адреса сайта всё равно включается поиск: вы ввели адрес сайта, но это не точный путь к серверу, где хранятся данные. Пока идёт запрос к данным, и пока они идут обратно, включаются несколько поисков на разных этапах.

Так же и здесь. По сути системе нужно достать некое значение из памяти. Массивы изначально заточены под машинную организацию памяти: по порядку. Логично предположить, что если вам нужно N-e значение, то оно быстрее достанется из памяти, так как оно N-e в самой памяти, начиная от некой ячейки (грубо говоря). Более сложные ассоциативные массивы (или объекты) организованы в памяти более сложно (извиняюсь за тавтологию). Ассоциативный массив - это, как минимум, два обычных массива. Соответственно, выполняя поиск по нему, работают уже минимум два поиска.

это всегда перебор всего массива каждый раз.

Если ключи уникальны, а в обычных javascript массивах это так, то вряд ли поиск продолжается после нахождения нужного элемента.

В целом веб-приложения это не совсем та сфера, где надо оптимизировать запросы, на базе архитектуры, я имею в виду, когда получаешь выигрыш в пару миллисекунд. Страница грузится пару секунд, анимации длятся 0.3с и так далее - на этом фоне выигрыш будет нулевой, даже с 1 миллиардом пользователей онлайн )

По существу вопроса, мне кажется, вы всё делаете совершенно правильно, потому что в вебе самое главное - это удобство постоянного развития проекта. Если код внешне, и по логике похож на то, как данные организованы в бытовом восприятии, это удобно: быстро вникаешь и можно дорабатывать.
Ответ написан
Комментировать
ivinnic
@ivinnic
Full-Stack - подустал
Добрый день

Написал два скрипта с замером времени поиска.

Search by object
let obj = {}

for(let i =0; i<1000; i++){
    obj['i'+i]=i
}

console.time('time')
for(let i =0; i<1000; i++){
const objResult = obj['i'+i];
}
console.timeEnd('time')


time: 0.156982421875ms

Search by array
let obj = []

for(let i =0; i<1000; i++){
    obj.push('i'+i)
}

console.time('time')

for(let i =0; i<1000; i++){
    const arrResult = obj.find(el => el === 'i'+i);
}
console.timeEnd('time')


time: 32.946044921875ms

Время конечно может отличатся, но в целом видится что поиск по массиву работаем медленнее обращения по ключу, по крайне мере в промышленном масштабе.
Ответ написан
saboteur_kiev
@saboteur_kiev
software engineer
Почему вы считаете, что обращение по ключу - не поиск?

Ключ это прямой адрес в памяти?
Нет, а значит наверное надо выполнить поиск по всем объектам, чтобы найти нужный по ключу?
Нужно смотреть реализацию геттера, чтобы понять насколько там все сложно.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы