Почему итерация по слайсу в Go обычно быстрее, чем по мапе?

Ответ

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

Слайс (Slice)

  1. Непрерывность в памяти: Элементы слайса располагаются в памяти друг за другом в виде непрерывного блока. Это позволяет процессору эффективно предзагружать данные в кэш (cache prefetching).
  2. Кеш-локальность (Cache Locality): Когда вы обращаетесь к одному элементу, соседние элементы с высокой вероятностью уже находятся в кэше процессора. Последующие обращения к ним происходят практически мгновенно, без обращения к медленной оперативной памяти.
  3. Простая арифметика: Доступ к элементу slice[i] — это простая арифметическая операция: адрес_начала_слайса + i * размер_элемента.
// Итерация по слайсу — очень быстрая операция
// благодаря предсказуемому доступу к памяти.
for i := 0; i < len(mySlice); i++ {
    _ = mySlice[i] // Быстрый доступ
}

Мапа (Map)

  1. Вычисление хеша: Для каждого ключа необходимо вычислить хеш-функцию, чтобы определить, в какой «корзине» (bucket) может находиться значение.
  2. Переходы по указателям: Мапа — это, по сути, массив указателей на корзины, которые могут содержать списки элементов для разрешения коллизий. Итерация требует постоянных переходов по указателям, что нарушает кеш-локальность.
  3. Обработка коллизий: Если несколько ключей имеют одинаковый хеш, они попадают в одну корзину. Для поиска нужного элемента требуется дополнительное сравнение ключей внутри корзины.
// Итерация по мапе — более медленная операция
for key, value := range myMap {
    // На каждой итерации: вычисление хеша, поиск корзины, доступ к элементу.
}

Ключевой вывод

  • Слайс оптимизирован для последовательного доступа к данным.
  • Мапа оптимизирована для быстрого доступа к элементу по ключу.

Выбор между ними всегда зависит от задачи: если вам нужен быстрый перебор всех элементов — ваш выбор слайс. Если вам нужен быстрый поиск, вставка или удаление по уникальному идентификатору — мапа незаменима.