JAVAPROGLIB Telegram 6957
📈 Big-O ≠ производительность

Часто выбор коллекции ограничивается только таблицей сложностей и на этом всё.

Но реальный кейс сложнее: средняя сложность ≠ реальная скорость в продакшне. JVM, кэш процессора, GC и паттерны доступа могут радикально поменять картину.

🔑 Главная мысль

Выбирайте коллекцию под сценарий использования, а не “по самой быстрой ячейке в таблице”.

1️⃣ ArrayList — быстр в чтение, но не во вставке

ArrayList хранит элементы в массиве → локальность памяти + CPU кэш → итерации летят.
Вставка в середину за O(n), но при небольших списках разница с LinkedList исчезающе мала.

🔧 Паттерн использования:

— 90% чтение, редкие вставки → идеально.
— Если заранее известно примерное кол-во элементов → задайте initialCapacity, иначе ArrayList будет несколько раз пересоздавать массив (copy O(n) на каждом росте).

📌 Факт:

В бенчмарках JMH даже при вставке в середину ArrayList часто быстрее LinkedList просто потому, что LinkedList платит за “pointer chasing” (скачки по памяти, cache-miss).

2️⃣ LinkedList — звучит круто, но редко нужен

Да, вставка/удаление в начало или конец за O(1).
Но get(i) = O(n), и каждый шаг = новый объект, новая ссылка → нагрузка на GC.

🔧 Паттерн использования:

— Когда нужна двусторонняя очередь с частыми удалениями/добавлениями в начало и конец.
— Во всех остальных случаях лучше ArrayDeque, он без лишних объектов и быстрее почти всегда.

📌 Факт:

LinkedList ест больше памяти: на каждый элемент два указателя + объект-узел.

3️⃣ HashMap / HashSet — быстрые, пока не наступил resize

HashMap даёт O(1) доступ при хорошем hashCode().

Но:
— Если хэши “плохие” → коллизии → O(log n)
— При достижении load factor 0.75 → resize → перераспределение всех бакетов (дорогая операция).

🔧 Паттерн использования:

— Когда нужен быстрый поиск по ключу без сохранения порядка или когда важно хранить уникальные элементы или строить словари/кэши по ключу.
— Если знаете примерное кол-во элементов → сразу задайте кол-во элементов в конструкторе new HashMap<>(N).

📌 Факт:

Начиная с Java 8 при коллизии, когда LinkedList становится длинным (по умолчанию ≥ 8 элементов) → список превращается в красно-чёрное дерево.

4️⃣ TreeMap / TreeSet — порядок стоит денег

Дают O(log n) доступ и всегда хранят ключи отсортированными.
Но если сортировка нужна редко, дешевле собрать HashMap и вызвать sorted() на стриме.

🔧 Паттерн использования:

— Когда важно поддерживать сортировку на каждой операции (напр. Top-N задач в приоритетной очереди).
— Не храните mutable-ключи, т.к. можно “потерять” элемент при изменении поля, участвующего в compareTo.

📌 Факт:

TreeMap хранит узлы с балансировкой (красно-чёрное дерево) → накладные расходы на память + сравнения ключей.

5️⃣ LinkedHashMap — скрытый герой для кэшей

LinkedHashMap поддерживает порядок вставки или порядок доступа (accessOrder=true).
Можно сделать LRU-кэш, переопределив removeEldestEntry.

🔧 Паттерн использования:

— Когда важен порядок, но сортировка не нужна.
— Когда нужно легко реализовать ограниченный кэш.

📌 Факт:

Каждый get() в режиме accessOrder вызывает перестановку в двусвязном списке → небольшие накладные расходы.

🐸 Библиотека джависта

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍229🔥4



tgoop.com/javaproglib/6957
Create:
Last Update:

📈 Big-O ≠ производительность

Часто выбор коллекции ограничивается только таблицей сложностей и на этом всё.

Но реальный кейс сложнее: средняя сложность ≠ реальная скорость в продакшне. JVM, кэш процессора, GC и паттерны доступа могут радикально поменять картину.

🔑 Главная мысль

Выбирайте коллекцию под сценарий использования, а не “по самой быстрой ячейке в таблице”.

1️⃣ ArrayList — быстр в чтение, но не во вставке

ArrayList хранит элементы в массиве → локальность памяти + CPU кэш → итерации летят.
Вставка в середину за O(n), но при небольших списках разница с LinkedList исчезающе мала.

🔧 Паттерн использования:

— 90% чтение, редкие вставки → идеально.
— Если заранее известно примерное кол-во элементов → задайте initialCapacity, иначе ArrayList будет несколько раз пересоздавать массив (copy O(n) на каждом росте).

📌 Факт:

В бенчмарках JMH даже при вставке в середину ArrayList часто быстрее LinkedList просто потому, что LinkedList платит за “pointer chasing” (скачки по памяти, cache-miss).

2️⃣ LinkedList — звучит круто, но редко нужен

Да, вставка/удаление в начало или конец за O(1).
Но get(i) = O(n), и каждый шаг = новый объект, новая ссылка → нагрузка на GC.

🔧 Паттерн использования:

— Когда нужна двусторонняя очередь с частыми удалениями/добавлениями в начало и конец.
— Во всех остальных случаях лучше ArrayDeque, он без лишних объектов и быстрее почти всегда.

📌 Факт:

LinkedList ест больше памяти: на каждый элемент два указателя + объект-узел.

3️⃣ HashMap / HashSet — быстрые, пока не наступил resize

HashMap даёт O(1) доступ при хорошем hashCode().

Но:
— Если хэши “плохие” → коллизии → O(log n)
— При достижении load factor 0.75 → resize → перераспределение всех бакетов (дорогая операция).

🔧 Паттерн использования:

— Когда нужен быстрый поиск по ключу без сохранения порядка или когда важно хранить уникальные элементы или строить словари/кэши по ключу.
— Если знаете примерное кол-во элементов → сразу задайте кол-во элементов в конструкторе new HashMap<>(N).

📌 Факт:

Начиная с Java 8 при коллизии, когда LinkedList становится длинным (по умолчанию ≥ 8 элементов) → список превращается в красно-чёрное дерево.

4️⃣ TreeMap / TreeSet — порядок стоит денег

Дают O(log n) доступ и всегда хранят ключи отсортированными.
Но если сортировка нужна редко, дешевле собрать HashMap и вызвать sorted() на стриме.

🔧 Паттерн использования:

— Когда важно поддерживать сортировку на каждой операции (напр. Top-N задач в приоритетной очереди).
— Не храните mutable-ключи, т.к. можно “потерять” элемент при изменении поля, участвующего в compareTo.

📌 Факт:

TreeMap хранит узлы с балансировкой (красно-чёрное дерево) → накладные расходы на память + сравнения ключей.

5️⃣ LinkedHashMap — скрытый герой для кэшей

LinkedHashMap поддерживает порядок вставки или порядок доступа (accessOrder=true).
Можно сделать LRU-кэш, переопределив removeEldestEntry.

🔧 Паттерн использования:

— Когда важен порядок, но сортировка не нужна.
— Когда нужно легко реализовать ограниченный кэш.

📌 Факт:

Каждый get() в режиме accessOrder вызывает перестановку в двусвязном списке → небольшие накладные расходы.

🐸 Библиотека джависта

#CoreJava

BY Библиотека джависта | Java, Spring, Maven, Hibernate




Share with your friend now:
tgoop.com/javaproglib/6957

View MORE
Open in Telegram


Telegram News

Date: |

Over 33,000 people sent out over 1,000 doxxing messages in the group. Although the administrators tried to delete all of the messages, the posting speed was far too much for them to keep up. How to build a private or public channel on Telegram? Telegram message that reads: "Bear Market Screaming Therapy Group. You are only allowed to send screaming voice notes. Everything else = BAN. Text pics, videos, stickers, gif = BAN. Anything other than screaming = BAN. You think you are smart = BAN. Public channels are public to the internet, regardless of whether or not they are subscribed. A public channel is displayed in search results and has a short address (link). More>>
from us


Telegram Библиотека джависта | Java, Spring, Maven, Hibernate
FROM American