Как распознавать бенчмарки, которые измеряют не то
Дэн Луу разбирает три вида бенчмарков: расчёты производительности «на салфетке», оценки ИИ-моделей и сравнение зимних и всесезонных шин.
Самый наглядный пример касается памяти и SSD. Таблица приписывает случайному чтению памяти задержку 20 нс, хотя итерации теста независимы и процессор выполняет несколько чтений параллельно. В тесте SSD смещение на один байт заставляет запрос на 8 КиБ при странице 4 КиБ затрагивать три страницы; запросы могут пересекаться и попадать в кэш. Последовательный тест после первого прохода повторно читает файл объёмом 1 ГиБ уже из кэша.
Разбор на сайте Дэна Луу стоит прочитать перед своими замерами. Проверяйте, какую величину измеряет код, есть ли зависимости между операциями и не подменяет ли кэш работу устройства. Затем сопоставляйте тестовую нагрузку со своей системой.
Дэн Луу разбирает три вида бенчмарков: расчёты производительности «на салфетке», оценки ИИ-моделей и сравнение зимних и всесезонных шин.
Самый наглядный пример касается памяти и SSD. Таблица приписывает случайному чтению памяти задержку 20 нс, хотя итерации теста независимы и процессор выполняет несколько чтений параллельно. В тесте SSD смещение на один байт заставляет запрос на 8 КиБ при странице 4 КиБ затрагивать три страницы; запросы могут пересекаться и попадать в кэш. Последовательный тест после первого прохода повторно читает файл объёмом 1 ГиБ уже из кэша.
Разбор на сайте Дэна Луу стоит прочитать перед своими замерами. Проверяйте, какую величину измеряет код, есть ли зависимости между операциями и не подменяет ли кэш работу устройства. Затем сопоставляйте тестовую нагрузку со своей системой.
А вы уже забрали свой подарок ко Дню программиста?
Мы в Tproger вместе с нашими друзьями собрали целую коробку подарков к вашему профессиональному празднику. Переходите по ссылке, трясите коробку и забирайте свой презент: https://tprg.ru/CscV
Мы в Tproger вместе с нашими друзьями собрали целую коробку подарков к вашему профессиональному празднику. Переходите по ссылке, трясите коробку и забирайте свой презент: https://tprg.ru/CscV
Cloudflare автоматизировала обмен ключами с серверами сайтов
Cloudflare включила Automatic Key Exchange по умолчанию для доменов. Функция касается защищённого соединения между прокси Cloudflare и сайтом. Раньше Cloudflare начинала обмен по TLS 1.3 с X25519; при другом выборе сервера повтор добавлял полный сетевой круг.
Теперь сервис ежедневно проверяет серверы отдельно от рабочего трафика и первой предлагает сильнейший поддерживаемый алгоритм, прежде всего постквантовый X25519MLKEM768. Изменение развёртывают на части трафика и отменяют, если число повторов растёт.
При развёртывании доля повторов снизилась примерно с 52% до 3,7%, а задержка на 90-м процентиле сократилась более чем на 150 мс. Сотни тысяч доменов получили постквантовые соединения без ручной настройки. Разбор Cloudflare пригодится тем, кто отвечает за TLS: в панели можно проверить режим и ограничения по стандартам.
Cloudflare включила Automatic Key Exchange по умолчанию для доменов. Функция касается защищённого соединения между прокси Cloudflare и сайтом. Раньше Cloudflare начинала обмен по TLS 1.3 с X25519; при другом выборе сервера повтор добавлял полный сетевой круг.
Теперь сервис ежедневно проверяет серверы отдельно от рабочего трафика и первой предлагает сильнейший поддерживаемый алгоритм, прежде всего постквантовый X25519MLKEM768. Изменение развёртывают на части трафика и отменяют, если число повторов растёт.
При развёртывании доля повторов снизилась примерно с 52% до 3,7%, а задержка на 90-м процентиле сократилась более чем на 150 мс. Сотни тысяч доменов получили постквантовые соединения без ручной настройки. Разбор Cloudflare пригодится тем, кто отвечает за TLS: в панели можно проверить режим и ограничения по стандартам.
Как балансировщик выбирает сервер и почему медианы недостаточно
Обстоятельный интерактивный разбор ведёт от циклической раздачи запросов к алгоритмам, которые учитывают состояние серверов. Симуляции показывают слабое место перебора: запросы различаются по времени обработки, серверы по мощности, а очередь сокращает отказы ценой задержки.
Автор сравнивает ручные и динамические веса, выбор сервера с наименьшим числом активных запросов и сочетание недавней задержки с числом открытых соединений. В его прогонах комбинированный алгоритм улучшил медиану, 95-й и 99-й процентили относительно выбора по числу соединений, но со временем потерял больше запросов. Результат зависел от настроек симуляции.
В статье на samwho.dev параметры меняются в симуляциях. Читать стоит тем, кто выбирает балансировку: сравнивайте медиану, хвостовые задержки, отказы и поведение под своей нагрузкой.
Обстоятельный интерактивный разбор ведёт от циклической раздачи запросов к алгоритмам, которые учитывают состояние серверов. Симуляции показывают слабое место перебора: запросы различаются по времени обработки, серверы по мощности, а очередь сокращает отказы ценой задержки.
Автор сравнивает ручные и динамические веса, выбор сервера с наименьшим числом активных запросов и сочетание недавней задержки с числом открытых соединений. В его прогонах комбинированный алгоритм улучшил медиану, 95-й и 99-й процентили относительно выбора по числу соединений, но со временем потерял больше запросов. Результат зависел от настроек симуляции.
В статье на samwho.dev параметры меняются в симуляциях. Читать стоит тем, кто выбирает балансировку: сравнивайте медиану, хвостовые задержки, отказы и поведение под своей нагрузкой.
Как устроен аллокатор памяти и почему свободных байтов может не хватить
Интерактивная статья ведёт от malloc и free к своему аллокатору. Сетка байтов позволяет видеть каждый запрос.
Карта разбора:
1. Простейший аллокатор выдаёт следующий участок, но не возвращает память: он не хранит границы блоков;
2. Универсальный хранит адрес и размер, а при освобождении объединяет соседние участки;
3. 6 свободных байтов не спасают, если они разбиты на два участка по 3 байта;
4. Минимальный блок в 4 байта в показанном примере снижает внешнюю фрагментацию, но при запросах по 1 байту оставляет неиспользованными 75% памяти.
Материал Memory Allocation стоит читать тем, кто хочет написать свой аллокатор. Выбирать способ распределения памяти нужно под размеры и порядок запросов программы: один алгоритм не подходит всем нагрузкам.
Интерактивная статья ведёт от malloc и free к своему аллокатору. Сетка байтов позволяет видеть каждый запрос.
Карта разбора:
1. Простейший аллокатор выдаёт следующий участок, но не возвращает память: он не хранит границы блоков;
2. Универсальный хранит адрес и размер, а при освобождении объединяет соседние участки;
3. 6 свободных байтов не спасают, если они разбиты на два участка по 3 байта;
4. Минимальный блок в 4 байта в показанном примере снижает внешнюю фрагментацию, но при запросах по 1 байту оставляет неиспользованными 75% памяти.
Материал Memory Allocation стоит читать тем, кто хочет написать свой аллокатор. Выбирать способ распределения памяти нужно под размеры и порядок запросов программы: один алгоритм не подходит всем нагрузкам.
Как устроены хеш-функции и зачем им равномерное распределение
Статья с интерактивными визуализациями показывает превращение строки в число и способы оценить результат. Коллизии неизбежны: если диапазон содержит 8 значений, среди 9 разных входов хотя бы два дадут одинаковое число.
Хорошая функция равномерно распределяет результаты и создаёт лавинный эффект: при изменении одного входного бита в среднем меняется 50% выходных.
Затем автор собирает на JavaScript хеш-таблицу из корзин: хеш ключа выбирает корзину, а поиск перебирает её элементы до совпадения. Статья Hashing связывает знакомый
Статья с интерактивными визуализациями показывает превращение строки в число и способы оценить результат. Коллизии неизбежны: если диапазон содержит 8 значений, среди 9 разных входов хотя бы два дадут одинаковое число.
Хорошая функция равномерно распределяет результаты и создаёт лавинный эффект: при изменении одного входного бита в среднем меняется 50% выходных.
murmur3 сравнивают с функцией, которая суммирует коды символов по модулю 1 000 000. На случайных строках разница почти незаметна, но числа от 1 до 1 000 образуют у простой функции узоры.Затем автор собирает на JavaScript хеш-таблицу из корзин: хеш ключа выбирает корзину, а поиск перебирает её элементы до совпадения. Статья Hashing связывает знакомый
Map с распределением данных и показывает, почему хеш-функцию нельзя оценивать только на случайном вводе.Как читать Rust-код: карта синтаксиса за полчаса
Это обстоятельный разбор базовой грамматики Rust. Автор читает множество коротких фрагментов и объясняет значение ключевых слов и символов.
Путь начинается с
A half-hour to learn Rust стоит открыть перед первым чтением Rust-кода. Страница обновлялась около семи лет назад: актуальные библиотеки и практики нужно сверять со свежей документацией, а основы синтаксиса здесь остаются удобной системой координат.
Это обстоятельный разбор базовой грамматики Rust. Автор читает множество коротких фрагментов и объясняет значение ключевых слов и символов.
Путь начинается с
let, типов и повторного объявления имени, которое создаёт новую переменную. Затем идут кортежи, функции и блоки-выражения. На примерах видно, почему отсутствие точки с запятой возвращает значение блока, как _ отбрасывает ненужный результат и чем вызов метода через точку отличается от :: в пути к имени. Отдельно разобраны импорт через use, автоматически доступные стандартные имена, структуры и их разбор на поля.A half-hour to learn Rust стоит открыть перед первым чтением Rust-кода. Страница обновлялась около семи лет назад: актуальные библиотеки и практики нужно сверять со свежей документацией, а основы синтаксиса здесь остаются удобной системой координат.
Как сделать распределённую блокировку безопасной
Процесс может зависнуть дольше срока блокировки, проснуться после передачи права другому узлу и затереть его запись. Сервис блокировок от этого не спасает.
В обстоятельном разборе распределённых блокировок Мартин Клеппманн разделяет две задачи:
— для экономии допустим редкий повтор работы;
— для корректности два владельца означают потерю данных или расхождение состояния.
Во втором случае нужен защитный порядковый номер. Сервис выдаёт при каждом захвате всё большее число, а хранилище отклоняет запоздалую запись с меньшим. Redlock такого числа не создаёт: пять серверов Redis и решение большинством не закрывают гонку.
Разбор пригодится тем, кто полагается на блокировку ради корректности. Проверьте, умеет ли хранилище отвергать устаревшие операции: проверки срока перед записью недостаточно, ведь процесс может остановиться после неё.
Процесс может зависнуть дольше срока блокировки, проснуться после передачи права другому узлу и затереть его запись. Сервис блокировок от этого не спасает.
В обстоятельном разборе распределённых блокировок Мартин Клеппманн разделяет две задачи:
— для экономии допустим редкий повтор работы;
— для корректности два владельца означают потерю данных или расхождение состояния.
Во втором случае нужен защитный порядковый номер. Сервис выдаёт при каждом захвате всё большее число, а хранилище отклоняет запоздалую запись с меньшим. Redlock такого числа не создаёт: пять серверов Redis и решение большинством не закрывают гонку.
Разбор пригодится тем, кто полагается на блокировку ради корректности. Проверьте, умеет ли хранилище отвергать устаревшие операции: проверки срока перед записью недостаточно, ведь процесс может остановиться после неё.
Как Discord перенёс триллионы сообщений с Cassandra на ScyllaDB
В обстоятельном разборе Discord показывает перестройку всего пути запроса. В начале 2022 года Cassandra состояла из 177 узлов, но один перегруженный раздел мог замедлить весь кластер.
Между API и базой появились сервисы данных на Rust. Одновременные запросы одной строки объединялись: базу опрашивала одна задача, остальные клиенты получали её результат. Маршрутизация по идентификатору канала направляла такие запросы в один экземпляр сервиса, чтобы объединение срабатывало чаще.
Готовый переносчик оценил миграцию в три месяца. Собственный вариант на Rust сократил оценку до девяти дней и переносил до 3,2 млн сообщений в секунду. Разбор пригодится при защите базы от всплесков и переходе без простоя: смены СУБД недостаточно, параллельные запросы нужно ограничивать до неё, а ответы двух систем сверять во время миграции.
В обстоятельном разборе Discord показывает перестройку всего пути запроса. В начале 2022 года Cassandra состояла из 177 узлов, но один перегруженный раздел мог замедлить весь кластер.
Между API и базой появились сервисы данных на Rust. Одновременные запросы одной строки объединялись: базу опрашивала одна задача, остальные клиенты получали её результат. Маршрутизация по идентификатору канала направляла такие запросы в один экземпляр сервиса, чтобы объединение срабатывало чаще.
Готовый переносчик оценил миграцию в три месяца. Собственный вариант на Rust сократил оценку до девяти дней и переносил до 3,2 млн сообщений в секунду. Разбор пригодится при защите базы от всплесков и переходе без простоя: смены СУБД недостаточно, параллельные запросы нужно ограничивать до неё, а ответы двух систем сверять во время миграции.
В 2001 году появился SpaceWeb — тогда же весь рунет жил в аське, разбирался с первыми сайтами и понятия не имел, что такое биткоин. К своему 25-летию компания вместе с Типичным программистом сделала анкету, которая возвращает в те годы: школьные вопросы про спорт, лучшего друга и обои на рабочий стол, а рядом — Winamp, QIWI-терминалы во дворах, Покемон Go и попытка заглянуть в будущее.
Как устроен асинхронный веб-краулер на Python
Обстоятельная глава строит краулер с нуля: от корневого URL он скачивает страницы, извлекает новые ссылки и ставит их в очередь. Число одновременных запросов ограничивают, чтобы избыток конкуренции не снижал производительность.
Разбор идёт от цикла событий с неблокирующими сокетами и колбэками к корутинам на генераторах, а затем к asyncio с асинхронной очередью. Переходы показывают, как избежать неуправляемых цепочек колбэков.
Асинхронность не означает параллельные вычисления и не обязана быть быстрее потоков. Она подходит для множества медленных соединений с редкими событиями, где поток на каждый запрос расходует память и упирается в системные ограничения.
В главе «A Web Crawler With asyncio Coroutines» из 500 Lines or Less код написан для Python 3.4. Читайте ради механики цикла событий; перед копированием сверяйте API с документацией.
Обстоятельная глава строит краулер с нуля: от корневого URL он скачивает страницы, извлекает новые ссылки и ставит их в очередь. Число одновременных запросов ограничивают, чтобы избыток конкуренции не снижал производительность.
Разбор идёт от цикла событий с неблокирующими сокетами и колбэками к корутинам на генераторах, а затем к asyncio с асинхронной очередью. Переходы показывают, как избежать неуправляемых цепочек колбэков.
Асинхронность не означает параллельные вычисления и не обязана быть быстрее потоков. Она подходит для множества медленных соединений с редкими событиями, где поток на каждый запрос расходует память и упирается в системные ограничения.
В главе «A Web Crawler With asyncio Coroutines» из 500 Lines or Less код написан для Python 3.4. Читайте ради механики цикла событий; перед копированием сверяйте API с документацией.
Как тестирование на основе свойств отделяет правило от примера
Обстоятельная статья Increment разбирает подход на Python и Hypothesis. Обычный тест проверяет проект с лимитом в 3 участника и тремя пользователями. Название обещает работу с любым лимитом, хотя код подтверждает только этот набор. Тест на основе свойств вместо одного примера задаёт допустимые входы и условие для каждого из них.
Hypothesis получает диапазоны входов через
На Argon2 подход нашёл старый баг: при
Обстоятельная статья Increment разбирает подход на Python и Hypothesis. Обычный тест проверяет проект с лимитом в 3 участника и тремя пользователями. Название обещает работу с любым лимитом, хотя код подтверждает только этот набор. Тест на основе свойств вместо одного примера задаёт допустимые входы и условие для каждого из них.
Hypothesis получает диапазоны входов через
@given. Здесь меняются название проекта и список пользователей с уникальными адресами, а лимит равен длине списка. Случайные детали тестовых данных перестают быть скрытыми требованиями.На Argon2 подход нашёл старый баг: при
hash_len=513 фиксированный буфер C-библиотеки приводил к ошибке проверки созданного хеша. Если поддерживаете тестовую базу, найдите тесты, чьи названия обещают больше одного примера, и отделите меняющиеся входы от проверяемого правила.Как конечные автоматы индексируют миллиарды строк
Обстоятельный разбор Эндрю Галланта показывает, как конечные автоматы хранят упорядоченные множества и словари. Строка становится последовательностью переходов, а общие состояния используются повторно. Проверка ключа требует не больше шагов, чем в нём символов, независимо от размера набора.
Далее библиотека
В лонгриде Эндрю Галланта разобраны границы: нужен быстрый доступ к произвольному участку файла, а структура не универсальна. Читать разработчикам поиска и словарей, чтобы оценить вариант индекса.
Обстоятельный разбор Эндрю Галланта показывает, как конечные автоматы хранят упорядоченные множества и словари. Строка становится последовательностью переходов, а общие состояния используются повторно. Проверка ключа требует не больше шагов, чем в нём символов, независимо от размера набора.
Далее библиотека
fst на Rust и опыты. Индекс 16 млн заголовков Wikipedia объёмом 384 МБ построился за 18,3 секунды и занял 157 МБ. Поиск по регулярному выражению занял 0,023 секунды, нечёткий поиск с двумя правками: 0,094 секунды. Финал: более 1,6 млрд URL из Common Crawl объёмом 134 ГБ.В лонгриде Эндрю Галланта разобраны границы: нужен быстрый доступ к произвольному участку файла, а структура не универсальна. Читать разработчикам поиска и словарей, чтобы оценить вариант индекса.
burntsushi.net
Index 1,600,000,000 Keys with Automata and Rust - Andrew Gallant's Blog