Числа Норриса в программировании кода
Перевод поста Norris Numbers, автор Lawrence Kesteloot
В 2011 году Джон Д. Кук написал следующую запись в блоге:
Мой друг Клифт Норрис определил фундаментальную константу, которую я называю числом Норриса - среднее количество кода, которое может написать необученный программист, прежде чем он или она ударится о стену. Клифт считает, что это 1 500 строк. После этого код становится настолько запутанным, что автор не может отладить или модифицировать его без чудовищных усилий.
Я не знаю достаточно начинающих программистов, чтобы подтвердить этот эффект, но я самостоятельно заметил следующую стену на пути программиста, которая возникает при 20 000 строк. Я изменю число Норриса на 2 000, чтобы получить хороший скачок в десять раз.
Я неоднократно сталкивался со стеной в 20 000 строк на своей первой работе после окончания колледжа, как и мои коллеги (которые были такими же молодыми, как и я). В DreamWorks у нас было 950 программ для аниматоров, и подсчет строк показал, что все большие программы были в районе 20 000-25 000 строк. Добавление дополнительных функций требовало слишком больших усилий.
В середине 1996 года мне было поручено написать инструмент освещения DreamWorks (вместе с двумя другими программистами), и я знал, что это будет намного больше, чем 20 000 строк кода. Я изменил свой подход к программированию, и через год инструмент был успешно реализован в объеме около 200 000 строк. (Его планируется вывести из эксплуатации в 2013 году, поскольку он использовался ежедневно в течение 16 лет для создания 32 фильмов). С тех пор я написал еще несколько программ в диапазоне от 100 000 до 200 000 строк. Я уверен, что упираюсь в следующую стену; я чувствую это.
Особенно трудно вести технические дискуссии с человеком, который не преодолел столько стен, сколько преодолели вы. Прорваться сквозь эти стены означает пойти на различные компромиссы, и в частности это означает принять решение, которое кажется менее разумным в краткосрочной перспективе, но поможет в дальнейшем. Это трудный аргумент - краткосрочные преимущества очевидны сразу, но я не могу убедить никого, что через год кто-то может внести невинное изменение, которое сломает этот код.
Эдсгер Дейкстра писал в 1969 году:
Годовалый ребенок будет ползать на четвереньках со скоростью, скажем, одна миля в час. Но скорость в тысячу миль в час - это скорость сверхзвукового реактивного самолета. Если рассматривать ребенка и реактивный самолет как объекты, способные к движению, то они несравнимы, поскольку все, что может сделать один, не может сделать другой, и наоборот.
Начинающий программист, о котором говорит Клифт Норрис, учится ползать, потом ходить, потом бегать, потом бегать, потом спринтовать, и он думает: "При таком ускорении я смогу достичь скорости сверхзвукового реактивного самолета!". Но он упирается в предел в 2000 линий, потому что его навыки не масштабируются. Чтобы ехать быстрее, он должен двигаться по-другому, используя автомобиль. Затем он учится водить машину, сначала медленно, потом быстрее, но упирается в ограничение в 20 000 строк. Навыки вождения не переходят в навыки управления реактивным самолетом.
Мой друг Брэд Грэнтэм объясняет это тем, что начинающий программист "перебирает" задачи. Я думаю, что это правильно: Когда код не превышает 2 000 строк, вы можете писать любой запутанный мусор и полагаться на то, что ваша память вас спасет. Продуманная декомпозиция классов и пакетов позволит вам увеличить масштаб до 20 000 строк.
В чем ключ к преодолению этого рубежа? Для меня это было сохранение простоты. Категорически отказывайтесь добавлять какую-либо функцию или строку кода, если она не нужна вам прямо сейчас, и нужна очень сильно. Я уже затрагивал эту тему в книге "Каждая строчка - потенциальная ошибка" (а до этого в книге "Простота - это хорошо"). Главный архитектор эффектов в DreamWorks сформулировал это так:
Для меня гениальность [инструмента освещения] заключалась в выборе небольшого набора функций, которые были доступны для написания и поддержки и достаточно сильны, чтобы сделать отличный инструмент освещения.
Как технический руководитель я вижу свой основной вклад в том, чтобы говорить "нет" тем функциям, которые коллеги считают важными, но не могут обосновать. Настоящий фокус в том, чтобы понять, когда новая функция добавляет линейную сложность (только собственный вес) или геометрическую сложность (взаимодействие с другими функциями). И того, и другого следует избегать, но последнее требует особо убедительного обоснования.
Например, по состоянию на 2012 год ядро Linux содержало 15 миллионов строк кода. Из них 75% имели линейную сложность (драйверы, файловые системы и код, специфичный для архитектуры); у вас могут быть десятки видеодрайверов, и они не взаимодействуют (сильно) друг с другом. Остальное - более геометрическая сложность.
Дийкстра говорит о том, что трудно обучать этим продвинутым техникам, потому что они имеют смысл только в программах на 20 000 или 200 000 строк. Любой класс или учебник должен ограничивать свои примеры несколькими сотнями строк, и метод грубой силы работает там просто отлично. Вам действительно нужно, чтобы учебник показал вам программу на 30 000 строк, а затем продемонстрировал новую функцию, которая была добавлена легко, потому что программа не была слишком сложной изначально. Но это фактически невозможно.
Опыт показывает, что доказанная способность человека отлично справляться с работой определенного масштаба отнюдь не является гарантией того, что, столкнувшись с гораздо большей работой, он не наделает в ней бед". -Эдсгер Дийкстра
Я не знаю, что мне придется изменить, чтобы преодолеть стену в 200 000 строк. В последнее время я перешел на более чисто функциональный стиль и избавляюсь от изменяемого состояния, и, возможно, это поможет мне прорваться.
И мне очень интересно посмотреть, что представляет собой барьер в 2 миллиона строк.
Кажется, что примерно на уровне 3-4M LOC возникает стена, и действительно, после 3M LOC скорость роста, похоже, значительно замедляется, независимо от количества людей (сотни) или лет (десятилетия). -Дан Векслер
Хотите больше полезных советов? Смотрите и подписывайтесь на наш канал! Здесь я публикую лучшие советы для пользователей Андроид, Windows, iOS и Mac OS. Также вы можете задать мне любой вопрос, подписавшись на канал.