Pull to refresh
1985
207.4

Переводчик-фрилансер

Send message

Самый тупой способ повышения производительности

Level of difficultyEasy
Reading time5 min
Reach and readers11K

Введение

Сегодня мне немного грустно, поэтому чтобы подбодрить себя, расскажу вам историю, самой, наверно, смехотворной задачи по оптимизации, которую мне поручали. Не знаю, извлечёте ли вы из неё что-то полезное, но, по крайней мере, кого-то она развеселит…

Читать далее

Взламываем 40-летний донгл защиты от копирования

Level of difficultyEasy
Reading time6 min
Reach and readers16K

Всё верно — это маленькое устройство стояло между мной и возможностью запускать ещё более старое ПО, которое я раскопал в процессе программной археологии.

Недавно я помогал бухгалтерской фирме друга мигрировать с крайне древнего программного пакета, которым они вынуждены были пользоваться последние четыре десятка лет.

Это ПО было написано на языке программирования RPG (Report Program Generator), который старше Кобола (!); он использовался в компьютерах IBM среднего ценового диапазона наподобие System/3, System/32 и вплоть до AS/400. Похоже, позже RPG портировали в MS-DOS, поэтому те же программные инструменты, написанные на RPG, могут работать на персональных компьютерах. Так фирма и оказалась в этой ситуации.

Эта бухгалтерская фирма работала на компьютере с Windows 98 (да, в 2026 году) и запускала написанное на RPG ПО в консольном окне DOS. Оказалось, что для работы ПО требовалось подключить к параллельному порту компьютера специальный аппаратный донгл защиты от копирования! В те времена это было достаточно распространённой практикой, особенно у поставщиков «корпоративного» ПО, защищавшего свои очень важные™ программы от неавторизованного применения.

Читать далее

Я создал вдвое более быстрый лексер, но обнаружил, что узким местом был ввод-вывод

Level of difficultyMedium
Reading time18 min
Reach and readers14K

Я создал лексер ассемблера ARM64 (ну, точнее, сгенерировал его из моего собственного генератора парсера, но пост не об этом), обрабатывающий код на Dart вдвое быстрее официального сканера. Этого результата я добился при помощи статистических методик надёжного измерения малых различий в производительности. Затем я провёл его бенчмарк на 104000 файлов и обнаружил, что узким местом был не мой лексер, а ввод-вывод. Это история о том, как я случайно узнал, почему pub.dev хранит пакеты в виде файлов tar.gz.

Читать далее

Структуры данных на практике. Глава 3: Бенчмаркинг и профилирование

Level of difficultyMedium
Reading time9 min
Reach and readers5.5K

Проблема измерений

Узнав из Главы 2 об иерархии памяти, вы, возможно, захотите оптимизировать свой код. Но есть одна проблема: как понять, что оптимизация на самом деле сработала?

Этот урок дорого мне обошёлся.

Я оптимизировал реализацию хэш-таблицы в загрузчике. Исходя из своего понимания поведения кэша, я переписал хэш-функцию так, чтобы она была «более дружественной к кэшу», и был уверен, что она станет быстрее.

Я запустил код. Мне показалось, что он быстрее. Я закоммитил изменения.

Неделю спустя коллега провёл бенчмарки и выяснил, что моя «оптимизация» замедлила код на 15%. Я оптимизировал не то, но у меня не было данных, чтобы подтвердить мои предположения.

Вывод: никогда не доверяйте своей интуиции, всегда проводите замеры.

В этой главе я расскажу, как измерять правильно. Мы создадим комплексный фреймворк бенчмаркинга и научимся эффективно использовать инструменты профилирования.

Читать далее

Я решил написать ухудшенный UUID по ничтожнейшим из причин

Level of difficultyEasy
Reading time7 min
Reach and readers5.6K

Вчера я баловался с проектом API, которым занимаюсь уже долгое время. Подобные проекты мы обычно переписываем снова и снова на протяжении многих лет, чтобы поддерживать высокий уровень дофамина от рефакторинга. Вы понимаете, о чём я. На этот раз совершенно внезапно я кое-что осознал. Мне нужно отрефакторить одну вещь. Я достаточно активно пользуюсь UUID, поэтому URL моих ресурсов очень длинные и некрасивые.

В зависимости от версии и варианта в UUID есть множество разной информации, но по большей мере это куча случайных битов, которые и обеспечивают свойство «универсальной уникальности», которое нам так нравится. Но если по какой-то причине вам не нравится проверенный временем стандарт с огромной экосистемой нативной поддержки... то эта статья для вас!

Читать далее

Структуры данных на практике. Глава 2: Иерархия памяти

Level of difficultyMedium
Reading time8 min
Reach and readers6.5K

«Память — это современный диск, диск — это современная лента», — Джим Грей

Проблема ста тактов

В Главе 1 мы говорили о том, что промахи кэша стоят 100-200 тактов, а попадания в кэш — всего 1-4 такта. И это не какая-то мелкая деталь, а самый важный фактор современной производительности.

Ниже я расскажу, почему это так.

Однажды я оптимизировал драйвер устройства для встраиваемой системы на RISC-V. Драйвер должен был обрабатывать пакеты от сетевого интерфейса, но при большой нагрузке мы теряли пакеты. CPU работал с частотой 1 ГГц, а для обработки каждого пакета требовалось около 500 команд. Простая математика:

500 команд ÷ 1 ГГц = 500 наносекунд на пакет

При скорости 500 нс на пакет мы могли бы обрабатывать 2 миллиона пакетов в секунду. Однако мы справлялись всего с 200 тысячами пакетов в секунду, то есть в десять раз меньше, чем ожидалось.

Профилировщик показан следующее:

$ perf stat -e cycles,instructions,cache-misses ./driver_test Performance counter stats:

5,000,000 cycles

500,000 instructions

45,000 cache-misses

Постойте-ка: 500000 команд должны занимать 500000 тактов (при 1 IPC). Но мы видим 5 миллионов тактов. Куда подевались лишние 4,5 миллиона тактов?

Читать далее

Гигабитный Ethernet через телефонную проводку

Level of difficultyEasy
Reading time7 min
Reach and readers26K

Я наконец-то разобрался, как реализовать гигабитный Ethernet по телефонным проводам.

Powerline-адаптер и огорчения

В последние годы я по большей мере пользовался адаптерами Интернета через электропроводку (powerline-адаптерами). Некоторые работали неплохо, другие нет. Тот, которым я пользовался долго, обеспечивал мне стабильные 30 Мбит/с: маловато, но этого было вполне достаточно для меня на то время. Мне важнее всего стабильно низкие задержки в играх, а не пропускная способность.

Вернёмся в настоящее: серьёзной проблемой было то, что powerline-адаптер регулярно терял соединение. Я купил новые, поддерживающие последний и самый лучший стандарт G.hn 2400 (можно купить несколько и вернуть те, которые не подойдут). Окончательно выбранный вариант обеспечивал скорость примерно 180 Мбит/с до моего домашнего офиса (с большим разбросом от 120 до 280 Мбит/с) и примерно 80 Мбит/с до верхнего этажа. Достаточно, чтобы смотреть YouTube/телевизор, но далеко неидеально.

Любопытная деталь: Интернет-провайдеры Великобритании не предлагают гигабитный Интернет. Они продают диапазоны скоростей наподобие 30 Мбит/с – 75 Мбит/с – 150 Мбит/с – 300 Мбит/с – 500 Мбит/с – 900 Мбит/с, каждый из которых стоит на несколько фунтов в месяц дороже предыдущего. Из-за этого Великобритания одновременно страна и с одним из самых дешёвых, и самых дорогих тарифов Интернета в мире.

Прошло время, я сменил место жительства, «железо», тариф, и теперь Интернет работает на скорости 500 Мбит/с.

Каждый апдейт Helldivers 2 на 50 ГБ (потому что эти идиоты выпускают один и тот же контент с пятикратным дублированием) становится мучительным напоминанием о том, что система работает не в полную силу.

Задача: как доставить 500 Мбит/с до моей комнаты?

Читать далее

Нет никаких доказательств успешности «браузерного эксперимента» Cursor

Level of difficultyEasy
Reading time4 min
Reach and readers15K

14 января 2026 года Cursor опубликовала пост «Scaling long-running autonomous coding» (https://cursor.com/blog/scaling-agents).

В этом посте компания рассказала о своих экспериментах с «автономной работой кодинг-агентов в течение нескольких недель» со следующей чётко поставленной целью:

понять, насколько далеко мы можем продвинуться в сфере кодинга в проектах, для выполнения которых командам разработчиков обычно требуются месяцы

Компания рассказала о подходах, которые она попробовала, о предполагаемых причинах их провала и о том, как решались эти проблемы.

Наконец она достигла этапа, на котором нечто «решило большинство наших проблем с координацией и позволило масштабироваться до очень больших проектов», что, в свою очередь, привело к следующему:

Чтобы протестировать эту систему, мы поставили перед собой амбициозную цель: создание веб-браузера с нуля. Агенты работали примерно неделю и написали больше миллиона строк кода в тысяче файлов. Исходный код можно посмотреть в GitHub (https://github.com/wilsonzlin/fastrender)

И здесь объяснения становятся немного запутанными и нечёткими. Компания заявляет, что «несмотря на размер кодовой базы, новые агенты всё равно понимают её и добиваются существенного прогресса» и что «сотни воркеров работают конкурентно, выполняя пушинг в одну и ту же ветвь с минимальными конфликтами», но ни разу не говорит, был ли проект успешным, работает ли он на самом деле. Можем ли мы сами запустить этот браузер? Это неясно, и компания ни разу не сделала подобных чётких заявлений.

Читать далее

Как удаление сорока строк увеличило производительность в 400 раз

Level of difficultyMedium
Reading time12 min
Reach and readers25K

У меня есть привычка раз в несколько недель вкратце просматривать лог коммитов OpenJDK. Многие коммиты слишком сложны для того, чтобы я мог разобраться с ними за то ограниченное время, которое я выделил для своего... специфичного хобби. Но иногда мне удаётся найти нечто любопытное.

На прошлой неделе моё внимание привлёк этот коммит:

858d2e434dd 8372584: [Linux]: Замена чтения proc для получения CPUtime потока на clock_gettime

diffstat выглядел интересно: +96 вставок, -54 удалений. В changeset был добавлен бенчмарк JMH из 55 строк, что означало реальное уменьшение кода продакшена.

Читать далее

Javascript: прощай, Date, здравствуй, Temporal

Level of difficultyEasy
Reading time13 min
Reach and readers19K

Время выставляет нас всех дураками, и JavaScript в этом не исключение. Честно говоря, меня это особо не задевало: по большей мере меня радуют маленькие странности JavaScript.

Мне нравится, когда можно увидеть обратную сторону; какой бы формальной и железобетонной ни казалась спецификация ES-262, мы всё равно замечаем (если знать, куда смотреть) в ней все хорошие и плохие решения, принятые сотнями людей, разрабатывавших язык. У JavaScript есть характер. Да, он не всегда делает всё в точности так, как можно ожидать, но на мой взгляд, JavaScript обладает настоящим очарованием, которое можно оценить, если глубоко его изучить.

Впрочем, существует одна часть языка, которая мне кажется совершенно нелогичной: это конструктор Date.

Читать далее

Баги в ядре Linux в среднем прячутся по 2 года. Некоторые скрываются до 20 лет

Level of difficultyEasy
Reading time16 min
Reach and readers7.2K

Прямо сейчас в вашем ядре есть баги, которые не найдут ещё многие годы. Я знаю это, потому что проанализировал 125183 бага с отслеживаемой меткой Fixes: за 20-летнюю историю Git ядра Linux.

Прежде чем баг обнаружат, он в среднем живёт в ядре 2,1 года. Но в некоторых подсистемах ситуация гораздо хуже: для драйверов шины CAN этот срок в среднем составляет 4,2 года, для сетевого протокола SCTP — 4,0 года. Самый долгоживущий баг в моём датасете (переполнение буфера в ethtool) прятался в ядре 20,7 года. Баг, который я проанализирую в статье подробно (утечка refcount в netfilter), прожил 19 лет.

Я создал инструмент, перехватывающий 92% исторических багов в тестовом датасете на этапе коммитов. Ниже я расскажу, какую информацию мне это дало.

Читать далее

А король-то голый! Как написать свой Claude Code в 200 строках кода

Level of difficultyEasy
Reading time7 min
Reach and readers25K

Современные кодинг-помощники кажутся магией. Достаточно описать нужное вам на хотя бы немного понятными словами, после чего они сами читают файлы, редактируют проект и пишут работающий код.

Но вот что я вам скажу: в основе этих инструментов не лежит магия. Для них достаточно примерно двухсот строк простого Python.

Давайте с нуля напишем собственный функциональный кодинг-агент.

Читать далее

Структуры данных на практике. Глава 1: Разрыв в производительности

Level of difficultyEasy
Reading time9 min
Reach and readers18K

Часть I: Основы

«В теории теория и практика одинаковы. На практике это не так». — авторство приписывается разными специалистам по computer science

Загадка

Два часа утра. Я смотрю на совершенно нелогичные данные профилирования.

В процессе работы над загрузчиком для SoC RISC-V у нас возникла проблема с производительностью. Загрузчик должен был искать конфигурации устройств в таблице: примерно пятьсот элементов, каждый с 32-битным ID устройства и указателем на данные конфигурации. Всё просто.

Мой коллега реализовал эту систему с помощью хэш-таблицы. «Поиск за O(1), — сказал он уверенно, — лучше уже некуда».

Но загрузчик работал медленно. Недопустимо медленно. Время загрузки должно было находиться в пределах 100 мс, но превышало это значение на три порядка.

Я попробовал использовать очевидную оптимизацию: заменить хэш-таблицу двоичным поиском по отсортированному массиву. Двоичный поиск занимает O(log n), что теоретически хуже, чем O(1). Так написано в учебниках. Мой преподаватель алгоритмов был бы разочарован.

Но в результате загрузчик оказался на 40% быстрее.

Как O(log n) смогло победить O(1)? Что происходит?

Читать далее

Насколько быстро браузеры могут обрабатывать данные в Base64?

Level of difficultyEasy
Reading time3 min
Reach and readers7.9K

Base64 — это схема кодирования двоичных значений в текст, преобразующая произвольные двоичные данные (например, изображения, файлы или любые байтовые последовательности) в безопасную печатную ASCII-строку, состоящую из 64-символьного алфавита (A–Z, a–z, 0–9, +, /). Браузеры применяют эту схему в JavaScript для встраивания двоичных данных непосредственно в код/HTML или для передачи двоичных данных в виде текста.

Недавно в браузерах появились удобные и безопасные функции для обработки Base64: Uint8Array.toBase64() и Uint8Array.fromBase64(). Хоть у них и есть множество параметров, смысл их сводится к кодированию и декодированию.

При кодировании они берут 24 бита из входных данных и разделяют их на четыре сегмента по 6 бит, и каждое 6-битное значение (в интервале от 0 до 63) соотносится с конкретным символом из алфавита Base64: первые 26 символов — это буквы A-Z в верхнем регистре, следующие 26 — a-z в нижнем, затем идут цифры 0-9 и, наконец, символы «+» и «/» в качестве 62-го и 63-го символов. Если длина входных данных не кратна трём байтам, то в качестве заполнителя используется знак «=».

Насколько же быстро могут работать эти функции?

Читать далее

Как должно выглядеть ревью кода в эпоху LLM

Level of difficultyEasy
Reading time3 min
Reach and readers10K

Недавно я активно занимался отправкой и проверкой пул-реквестов проекта PyTorch, созданных с существенной помощью LLM. Этот процесс сильно отличается ситуации в начале года, когда было понятно, что LLM вполне подходит для проектов, создаваемых с нуля, но для кодовой базы в продакшене их код оставался безнадёжно низкокачественным. Можете посмотреть мои смердженные PR, в описании которых упоминается Claude Code; у Джейсона Энсела тоже был подобный опыт (ссылка на Meta*; также есть список issue, на которые он ссылался в совей статье). Сейчас всё активнее обсуждается (Саймон УиллисонLLVM) то, как процесс код-ревью должен адаптироваться к этой новой эпохе LLM. Мой вклад в эти обсуждения таков: внутри команд код-ревью должен поменяться, превратившись в первую очередь в механизм согласования с человеком.

Читать далее

Как на самом деле выглядит необработанное фото

Level of difficultyEasy
Reading time3 min
Reach and readers30K

Вот фотография новогодней ёлки в том виде, в котором видит матрица камеры.

Она даже не чёрно-белая, а серо-серая.

Причина этого в том, что хотя аналогово-цифровой преобразователь (АЦП) камеры теоретически способен выдавать значения от 0 до 16382, данные не покрывают весь этот диапазон.

Читать далее

Заменяем JS обычным HTML

Level of difficultyEasy
Reading time6 min
Reach and readers19K

Уже многие годы JavaScript остаётся «рабочей лошадкой» веба. Если вам нужно сделать то, что невозможно реализовать средствами HTML и CSS, то обычно найти решение помогает JS. И это замечательно! JS помог расширить возможности пользователей, а также стимулировал прогресс HTML и CSS!

Но время идёт, функции HTML и CSS расширяются, поэтому мы должны начать заменять старые и привычные решения на JS новыми, требующими меньше JS.

Я ничего не имею против JS, но у него есть иные задачи, кроме как управление аккордеонами и внеэкранными меню навигации... Кроме того, JS нужно скачивать, распаковывать, обрабатывать, после чего он ещё часто тратит память на мониторинг и поддержку фич. Если мы сможем перенести какую-то функциональность JS в нативный HTML или CSS, тогда пользователям придётся скачивать меньше данных, а оставшийся JS сможет уделить внимание более важным задачам, с которыми (пока) не справляются HTML и CSS.

В этой статье я приведу несколько примеров; сможете придумать свои?

Читать далее

«История игрушек» уже не такая, какой вы её помните

Level of difficultyEasy
Reading time7 min
Reach and readers15K

«История игрушек» выглядела иначе, но объяснить это будет немного сложно.

В 1995 году компьютерная графика была самой важной темой в индустрии, и в центре этого ажиотажа находилась Pixar. Эта студия уже заставила Disney перейти на компьютеры и выиграла первый Оскар за компьютерную короткометражку (Tin Toy). ПО Pixar использовалось в крупных голливудских фильмах наподобие «Парка юрского периода».

Следующим шагом стала «История игрушек» (Toy Story), которую рекламировали как первую анимационную картину, полностью созданную в компьютерной графике1. Даже после предыдущих успехов Pixar этот шаг оставался рискованным. Будут ли продаваться билеты на полностью цифровой фильм?

Как мы уже знаем, у студии всё получилось. «Историю игрушек» выпустили тридцать лет назад, в ноябре 1995 года, и её популярность сформировала тот мир анимации, в котором мы живём сейчас. Индустрию покорил новый технологический процесс.

Читать далее

Как древняя чума изменила человечество 5000 лет назад

Reading time10 min
Reach and readers16K

У историков, изучающих болезни, возникла проблема. При исследовании образцов ДНК древнего человека генетики обнаружили гены, принадлежащие бактерии чумы Yersinia pestis, и это означало, что её эпидемия бушевала в Евразии пять тысяч лет назад. То есть почти за 3500 лет до «первой чумы», названной Юстиниановой по имени властвовавшего тогда римского императора. Как назвать этот обнаруженный «приквел» эпидемии? Сейчас самое популярное название — это чума позднего неолита и бронзового века (Late Neolithic-Bronze Age, LNBA), но это слишком уж многословно. Однако у учёных есть и другие причины для беспокойства. Есть вероятность, что это открытие станет ещё одним гвоздём в крышку гроба давно сложившегося убеждения о том, когда и почему человечество обрело множество влияющих на нас сегодня инфекционных заболеваний. В образцах, взятых у древних людей, обнаружилась галерея доисторических ужасов. Эти так называемые зоонозные заболевания донимали животных ещё до того, как перенеслись на человека, поэтому считается, что они совершили этот межвидовой переход после изобретения человечеством сельского хозяйства примерно двенадцать тысяч лет назад. Но в процессе изучения генетиками всё более глубоких слоёв прошлого обнаруживается, что переход произошёл гораздо позже — крупномасштабные вспышки происходили в Европе, как вы уже могли догадаться, примерно пять тысяч лет назад. Эти открытия не только покончили со старыми представлениями об эволюции заболеваний, но и заставили нас переосмыслить поворотный доисторический период. Как в то время распространялись болезни? Действовали ли тогда патогены так же, как и сегодня? Могла ли сама чума стать причиной бронзового века, заложив фундамент европейской цивилизации?

Читать далее

Когда компиляторы удивляют

Level of difficultyEasy
Reading time2 min
Reach and readers12K

Компиляторы то и дело удивляют меня очень хитрыми трюками. Когда я впервые увидел эту оптимизацию, то едва смог поверить в её реальность. Я изучал оптимизацию циклов и написал простую функцию, суммирующую все числа до заданного значения...

Читать далее
1
23 ...

Information

Rating
Does not participate
Location
Россия
Registered
Activity