Позвольте рассказать вам историю о самой дорогой точке с запятой, с которой мне когда-либо приходилось сталкиваться. В прошлом году моей команде досталась старая система обработки платежей, которая обрабатывала 14 миллионов долларов в день. Предыдущие разработчики уделяли такое внимание «чистому коду», что для работы системе потребовалось 47 микросервисов, хотя с этой задачей мог справиться один хорошо оптимизированный сервис. Их код был безупречен. Их архитектура напоминала картину Джексона Поллока, созданную диаграммами Венна. Система эффектно потерпела неудачу в Чёрную пятницу.
Вот почему у меня развился здоровый скептицизм по отношению к догмам читаемости кода. Давайте разберём этот культ чистоты, прежде чем ваш следующий отчёт о производительности станет некрологом вашей карьеры.
Индустриальный комплекс читабельности
Мы все были обработаны мантрами вроде:
- «Всегда предпочитайте читаемость хитростям!»
- «Код читают больше, чем пишут!»
- «Если его трудно читать, это плохой код!»
Эти утверждения содержат долю правды… как в коробках с хлопьями есть надпись «часть сбалансированного завтрака». Давайте посмотрим на фактические данные из производственных систем:
# Чистая версия (32 мс на операцию)
def calculate_discount(user):
return user.loyalty_years * 0.05 if user.loyalty_years < 5 else 0.15
# «Нечитаемая» оптимизированная версия (9 мс на операцию)
def calculate_discount(u):
return 0.15 if u.ly >=5 else u.ly*0.05
Когда этот код выполняется 28 миллионов раз в день на платформе электронной коммерции, разница в 23 мс приводит к ежедневной экономии 644 часов. Но рецензенты кода всё равно потребуют от вас «переименовать u
в user
для ясности».
Когда читабельность не оплачивает счета
Пример 1: Бунт битового сдвига
Рассмотрим эту распространённую операцию из программирования графики:
// «Читаемая» версия
int DoublePixelValue(int pixel) {
return pixel * 2;
}
// «Загадочная» версия
int DoublePixelValue(int pixel) {
return pixel << 1;
}
Версия с битовым сдвигом выполняется за 2 тактовых цикла против 5 для умножения. При обработке видео 8K со скоростью 120 кадров в секунду эта разница предотвращает самопроизвольное возгорание вашего рендер-сервера. Однако младшие разработчики по-прежнему будут настаивать на том, что первая версия «чище».
Пример 2: Кража локальности кэша
Эта красиво структурированная архитектура соответствует каждому принципу чистого кода… и работает медленно, как ленивец под действием снотворного. Разрушение слоёв для обеспечения локальности кэша сократило время отклика нашего поискового API с 99-го процентиля с 1,4 секунды до 89 мс. Код потерял свой идеальный рейтинг SOLID, но приобрёл способность выдерживать нагрузку Reddit.
Искусство стратегической неряшливости
- Первая помощь на горячем пути
Используйте инструменты профилирования для выявления критических путей:Только оптимизируйте (и потенциально запутывайте) код в самых высоких башнях пламени.
# Найдите горящее здание вашего приложения perf record -g -- ./your_app flamegraph > fire.html
- Сортировка документации
Добавляйте поясняющие комментарии к неочевидным оптимизациям:
// Использование побитового ИЛИ для более быстрой упаковки перечисления в 2 раза // Смотрите тест производительности #JB-228 для получения показателей int packed = FLAG_A | FLAG_C | (statusCode << 4);
- Правило 10x Если оптимизация обеспечивает улучшение менее чем на 10%, но увеличивает затраты на обслуживание — откажитесь от неё. Если она даёт улучшение более чем в 10 раз — запустите её в работу, даже если это заставит дядю Боба плакать.
Место читабельности в пантеоне
Это не манифест против читабельности. Это призыв к контекстно-зависимому кодированию:
- Прототип кода? Сделайте упор на читаемость.
- Обработка горячего цикла на скорости 10 миллионов оборотов в минуту? Сначала сделайте его быстрым.
- Команда новичков? Делайте упор на чистоту.
- Опытные специалисты? Доверяйте их навыкам расшифровки.
Инцидент с left-pad в экосистеме JavaScript доказал, что чрезмерная модульность приводит к уязвимости. Иногда небольшой контролируемый хаос делает системы более устойчивыми.
Заключение: Дзен беспорядка в коде
Нож шеф-повара чистый. Скальпель полевого медика чистый. Моторный отсек победившей машины Формулы-1? Великолепное, маслянистое, точно хаотичное творение.
Вашему коду нужны как стерильные зоны, так и грязные мастерские. Искусство заключается в том, чтобы знать, где провести черту — желательно с комментарием, который гласит: «// Прости меня, будущее я, но это заставляет денежный принтер работать».