ПИШЕМ САМЫЙ БЫСТРЫЙ хеш для кэширования данных Роман Елизаров Devexperts http://elizarov.livejournal.com Преждевременная оптимизация! http://www.flickr.com/photos/lofink/4501610335/ http://odetocode.com/Blogs/scott/archive/2008/07/15/optimizing-linq-queries.aspx Проблемы со скоростью? Где? Почему? Какие? Вам точно надо их решать? Формулируем задачу Четко. Кратко. Измеримо. Пример задачи 1. Работаем с заявками 2. Их много, они нужны часто 3. Хотим их кэшировать в памяти Моделируем нагрузку http://www.vsemayki.ru/product/19329/woman/ Пример нагрузки ~1М заявок в кэше 10М запросов getById Геометрическое распределение id Что будем измерять? Время Память Избежим типичных ошибок Помним • JIT компиляция и оптимизация кода • Сборка мусора Так что будем измерять? Среднее время одной итерации Пишем код для замеров Ищем готовые решения http://gizmod.ru/2009/05/29/zweistil--universalnyj_velosiped_s_motorchikom/ Разные реализации хеш-таблиц Время, нс на операцию 600 508 500 459 400 300 216 200 156 143 101 100 0 HashMap Guava high-scale-lib Trove Javolution HPPC Не цифрами едиными! RTSL http://www.cafepress.com/researchit.640209934 Что мешает скорости? Время, нс на операцию 600 500 Функционал Гарантии real-time 400 300 Thread-safety 200 100 0 HashMap Guava high-scale-lib Trove Javolution HPPC Вечный конфликт Универсальность Скорость Дизайн своего решения Производительность никогда не появляется случайно, только по замыслу авторов. Из чего складывается скорость? Алгоритм и структуры данных Реализация Результат Выбираем алгоритм • Д. Кнут «Искусство программирования» • Т. Кормен и др. «Алгоритмы: построение и анализ» • С. Скиена «Алгоритмы. Руководство по разработке» Хеш-таблицы Прямая адресация Открытая адресация Линейное исследование Двойное хеширование Хеш-таблицы И что работает быстрее? Прямая А это зависит от Открытая адресация адресация реализации и железа Линейной исследование Двойное хеширование Что используют другие? Время, нс на операцию 600 500 Прямая адресация Открытая адресация 400 300 200 100 0 HashMap Guava high-scale-lib Trove Javolution HPPC Память – это новый диск http://www.flickr.com/photos/gudlyf/6687607947/lightbox/ Меньше памяти занимает – быстрее работает* * При прочих равных Проверим … Занимая память x100 KB 800 700 600 500 400 300 200 100 0 HashMap Guava high-scale-lib Trove Javolution HPPC Меньше памяти использует – быстрее работает* * При прочих равных Порядок оптимизации при дизайне Занимаемая память Используемая память Другие детали Выберем структуру данных Открытая адресация – один массив Оценим потребление памяти Занимая память x100 KB 800 700 600 500 400 300 200 100 0 Выберем алгоритм (1) Линейное исследование • Проще • Доступ к соседним ячейкам • Более чувствительно к качеству хеш-функции • High-scale-lib, HPPC Двойное хеширование • Больше кода • В случае промаха прыгает в новое место • Требует две независимые хеш-функции • Trove Выберем алгоритм (2) Хеш-функция умножением • Быстрая • Работает с таблицами размером 2K • Требует выбора магического числамножителя Хеш-функция делением • Медленней – Но память еще медленней! • Лучше всего работает с таблицами простого размера • Trove High-scale-lib – не использует хеш-функцию HPPC – использует MurmurHash3 Как их комбинировать? Проще всего Линейное исследование Двойное хеширование Хеш-функция умножением Хеш-функция делением Напишем же! Магия золотого сечения 5 1 2 Равномерно размазывает последовательные числа по таблице Замерим скорость Время, нс на операцию 800 700 600 500 400 300 200 100 0 508 459 216 143 101 156 83 Важно распределение вероятности доступа к разным элементам Наиболее часто используемые заявки (последние) имеют соседние id Каждая деталь имеет значение http://car-interior-supplies.carinteriorss.co.uk/detail/ А если набор часто используемых id случаен? Время, нс на операцию 800 700 600 500 400 300 200 100 0 529 463 253 162 125 158 81 Общий процесс Формулировка задачи Структура данных Модель нагрузки Готовые решения Алгоритм Проверка и замеры* * Повторить с начала по необходимости Спасибо за внимание Роман Елизаров elizarov@devexperts.com Специальная благодарность: Денису Кисловскому Хотите знать больше? Все подробности, код и обсуждение: http://elizarov.livejournal.com Ваши комментарии важны для меня