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: |

Just as the Bitcoin turmoil continues, crypto traders have taken to Telegram to voice their feelings. Crypto investors can reduce their anxiety about losses by joining the “Bear Market Screaming Therapy Group” on Telegram. While the character limit is 255, try to fit into 200 characters. This way, users will be able to take in your text fast and efficiently. Reveal the essence of your channel and provide contact information. For example, you can add a bot name, link to your pricing plans, etc. Commenting about the court's concerns about the spread of false information related to the elections, Minister Fachin noted Brazil is "facing circumstances that could put Brazil's democracy at risk." During the meeting, the information technology secretary at the TSE, Julio Valente, put forward a list of requests the court believes will disinformation. Other crimes that the SUCK Channel incited under Ng’s watch included using corrosive chemicals to make explosives and causing grievous bodily harm with intent. The court also found Ng responsible for calling on people to assist protesters who clashed violently with police at several universities in November 2019. Administrators
from us


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