Макилрой убеждает нас великодушно
1.6.13. Правило экономии: время программиста стоит дорого; поэтому экономия его времени более приоритетна по сравнению с экономией машинного времени
"В ранние мини-компьютерные времена Unix" вынесенная в заголовок идея была довольно радикальной (машины тогда работали намного медленнее и были более дорогими). В настоящее время, когда каждая группа разработчиков и большинство пользователей (за исключением нескольких лабораторий по моделированию ядерных взрывов или созданию ЗО-анимации) обеспечены дешевыми машинными циклами, она может показаться слишком очевидной, чтобы о ней говорить.
Хотя почему-то практика, видимо, отстает от реальности. Если бы этот принцип принимался действительно серьезно в процессе разработки программного обеспечения, то большинство приложений были бы написаны на высокоуровневых языках типа Perl, Tel, Python, Java, Lisp и даже на языках командных интерпретаторов — т.е. на языках, сокращающих нагрузку на программиста, осуществляя собственное управление памятью ([65]).
И это действительно происходит в мире Unix, хотя за его пределами большинство разработчиков приложений, кажется, не в состоянии отойти от стратегии старой школы Unix, предполагающей кодирование на С (или С++). Данная стратегия и связанные с ней компромиссы подробнее описаны далее в настоящей книге.
Другим очевидным способом сохранения времени программиста является "обучение машины" выполнять больше низкоуровневой работы по программированию, что приводит к формулировке следующего правила.
1.6.14. Правило генерации: избегайте кодирования вручную; если есть возможность, пишите программы для создания программ
Известно, что люди плохо справляются с деталями. Соответственно, любой вид ручного создания программ является источником задержек и ошибок. Чем проще и более абстрактной может быть программная спецификация, тем более вероятно, что проектировщик реализует ее правильно. Сгенерированный код (на
Общеизвестно, что это на самом деле так (в конце концов, именно поэтому созданы компиляторы и интерпретаторы), однако зачастую никто не задумывается о последствиях. Изобилующий повторениями код на языке высокого уровня, написание которого утомительно для людей, является такой же продуктивной целью для генератора кода, как машинный код. Использование генераторов кода оправдано, когда они могут повысить уровень абстракции, т.е. когда язык спецификации для генератора проще, чем сгенерированный код, и код впоследствии не потребует ручной доработки.
В традициях Unix генераторы кода интенсивно используются для автоматизации чреватой ошибками кропотливой работы. Классическими примерами генераторов кода являются грамматические (parser) и лексические (lexer) анализаторы. Более новые примеры — генераторы шаке-файлов и построители GUI-интерфейсов.
Данные методики рассматриваются в главе 9.
1.6.15. Правило оптимизации: создайте опытные образцы, заставьте их работать, прежде чем перейти к оптимизации
Самый основной аргумент в пользу создания прототипов впервые был выдвинут Керниганом и Плоджером (Plauger): "90% актуальной и реальной функциональности лучше, чем 100% функциональности перспективной и сомнительной". Первоначальное создание прототипов помогает избежать слишком больших затрат времени для получения минимальной выгоды.
По несколько другим причинам Дональд Кнутт (автор книги
Поспешная оптимизация до выяснения узких мест в программе, возможно, является единственной ошибкой, которая разрушила больше конструкций, чем излишнее наращивание функциональности. Искаженный код и непостижимое расположение данных — результат приоритета скорости и оптимизации использования памяти или дискового пространства за счет прозрачности и простоты. Они порождают бесчисленные ошибки и выливаются в миллионы человеко-часов — часто только для того, чтобы получить минимальную выгоду от использования какого-либо ресурса, гораздо менее дорогостоящего, чем время отладки.