Репост из: eapotapov.am
Пока меня тянет на низкоуровневое программирование, вот вам интересное видео с недавней конференции GOTO о том, как докладчик участвовал в соревновании на то, чтобы сделать максимально быструю агрегацию файла с миллиардом строк с информацией о погоде на Java. На старте время выполнения занимало 5 минут, а в конце — 1,5 секунды.
Если лень смотреть, вот саммари (простите за стиль, я сделал транскрипцию видео, а потом суммаризировал в Claude и подправил стиль, но все-таки немного кривовато):
Задача:
Обработать файл с миллиардом строк погодных данных, содержащий названия городов и температуры. Базовая реализация занимала около 5 минут.
Наблюдение, обучение, адаптация, эксперименты (06:07):
Первым этапом все стали загружать свои версии на GitHub и делиться базовыми, самыми простыми оптимизациями.
"You don't have to be an engineer to be a racing driver, but you do have to have Mechanical Sympathy" (08:00):
Автор объясняет важность понимания работы процессора и памяти для оптимизации кода.
Температура как Int (09:32):
Оптимизация, заключающаяся в использовании целых чисел вместо чисел с плавающей точкой для представления температуры.
Memory-mapped файлы (10:37):
Использование этой техники для быстрого доступа к данным файла.
Использование unsafe (11:54):
Применение небезопасных методов Java для прямого доступа к памяти.
SWAR (13:31):
Использование техники SIMD (Single Instruction, Multiple Data) для обработки нескольких байтов одновременно.
Безстроковая обработка (17:22):
Оптимизация, позволяющая избежать создания объектов String.
Бесветвленное программирование (18:18):
Техника оптимизации, позволяющая избежать условных переходов в коде.
Вот тут классно: автор решил не использовать if-ы. Процессор пытается предсказать код, который будет выполняться далее, еще до выполнения if-а. Если он ошибется, это приведет к падению производительности. Это может не сильно влиять в общем случае, но если вы уже боретесь за секунды оптимизации, то имеет смысл.
Парсинг температуры (20:35):
Детальное описание оптимизированного алгоритма парсинга температуры.
Мы знаем формат строк, мы знаем разделитель, мы можем переписать parseInt так, чтобы это выполнялось гораздо быстрее с помощью булевой логики.
Отслеживание данных (30:14):
Реализация собственных хэш-таблиц.
Выбор JVM (36:22):
Эксперименты с различными реализациями Java Virtual Machine.
Graal и нативная компиляция (37:21):
Использование GraalVM для компиляции Java-кода в нативный исполняемый файл.
Итоги (39:38):
Краткое изложение основных оптимизаций и их влияния на производительность.
Результаты (40:50):
Финальные результаты соревнования, где время выполнения было сокращено с почти 5 минут до примерно 1,5 секунд.
https://www.youtube.com/watch?v=EFXxXFHpS0M
Если лень смотреть, вот саммари (простите за стиль, я сделал транскрипцию видео, а потом суммаризировал в Claude и подправил стиль, но все-таки немного кривовато):
Задача:
Обработать файл с миллиардом строк погодных данных, содержащий названия городов и температуры. Базовая реализация занимала около 5 минут.
Наблюдение, обучение, адаптация, эксперименты (06:07):
Первым этапом все стали загружать свои версии на GitHub и делиться базовыми, самыми простыми оптимизациями.
"You don't have to be an engineer to be a racing driver, but you do have to have Mechanical Sympathy" (08:00):
Автор объясняет важность понимания работы процессора и памяти для оптимизации кода.
Температура как Int (09:32):
Оптимизация, заключающаяся в использовании целых чисел вместо чисел с плавающей точкой для представления температуры.
Memory-mapped файлы (10:37):
Использование этой техники для быстрого доступа к данным файла.
Использование unsafe (11:54):
Применение небезопасных методов Java для прямого доступа к памяти.
SWAR (13:31):
Использование техники SIMD (Single Instruction, Multiple Data) для обработки нескольких байтов одновременно.
Безстроковая обработка (17:22):
Оптимизация, позволяющая избежать создания объектов String.
Бесветвленное программирование (18:18):
Техника оптимизации, позволяющая избежать условных переходов в коде.
Вот тут классно: автор решил не использовать if-ы. Процессор пытается предсказать код, который будет выполняться далее, еще до выполнения if-а. Если он ошибется, это приведет к падению производительности. Это может не сильно влиять в общем случае, но если вы уже боретесь за секунды оптимизации, то имеет смысл.
Парсинг температуры (20:35):
Детальное описание оптимизированного алгоритма парсинга температуры.
Мы знаем формат строк, мы знаем разделитель, мы можем переписать parseInt так, чтобы это выполнялось гораздо быстрее с помощью булевой логики.
Отслеживание данных (30:14):
Реализация собственных хэш-таблиц.
Выбор JVM (36:22):
Эксперименты с различными реализациями Java Virtual Machine.
Graal и нативная компиляция (37:21):
Использование GraalVM для компиляции Java-кода в нативный исполняемый файл.
Итоги (39:38):
Краткое изложение основных оптимизаций и их влияния на производительность.
Результаты (40:50):
Финальные результаты соревнования, где время выполнения было сокращено с почти 5 минут до примерно 1,5 секунд.
https://www.youtube.com/watch?v=EFXxXFHpS0M