Не в момент выполнения, а в момент проектирования

Original author: Bill Sourour
  • Translation
image

Давным-давно мудрый старый разработчик дал мне совет, который до недавнего времени я не очень ценил.

Во время код ревью мы рассматривали некоторую функцию, которая требовала, чтобы программа выводила список букв A-Z (например, список контактов с набором кнопок, которые позволяют переходить к именам, начинающимся с определенной буквы).

Итак, появился молодой преуспевающий программист. (Хорошо, это был я.) Я решил, что вместо хардкода массива всех букв будет проще написать цикл for, который проходит от 65 до 90, а затем генерировал буквы по полученному коду символа.

В варианте JavaScript это будет выглядеть примерно так:

for (let i = 65; i <= 90; i++) {
 letters.push(String.fromCharCode(i))
}

Мудрый старый разработчик посмотрел на меня и спросил, почему я просто не захардкодил этот массив. Это не выглядит так, как будто алфавит будет отличаться от одного сеанса к другому. Так зачем каждый раз вычислять его?
EDISON Software - web-development
Статья переведена при поддержке компании EDISON Software, которая разрабатывает систему диагностики хранилища документов Vivaldi, а также инвестирует в стартапы.

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

«Хорошо», сказал он. «Просто используйте этот функционал во время разработки, чтобы сгенерировать массив, а затем скопируйте и вставьте его в рабочий код».

А затем он сказал это:
«Избегайте во время выполнения программ то, что вы можете делать во время разработки»
Теперь давайте будем честными. Мой маленький цикл for не собирался замедлять приложение. И современные машины будут так быстро разбираться в этом коде, что никто даже не заметит. Но, как правило, это мудрый совет.

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

Вот почему я думаю, что в ближайшие годы такие известные игроки, как Wordpress, Drupal и т. п., столкнутся с серьезной проблемой со стороны таких генераторов статических сайтов, как Gatsby, Hugo или Jekyll, в сочетании с плавным процессом сборки, headless CMS, дешевыми CDN и быстрым непрерывным процессом интеграции.

Этот паттерн был назван JAMstack, что означает «JavaScript, API и стек разметки». И результаты весьма впечатляющие.

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

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

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

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

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

  • Я поделился своими собственными советами и извлеченными уроками в недавнем интервью на подкасте Developer On Fire, которое вы можете прослушать здесь.
  • Вы можете познакомится с JAMstack на Jamstack.org
  • В блоге Netlify также есть хороший обзор генераторов статических сайтов.
  • А вот статья о конкретном стеке, который я недавно рассмотрел и рекомендовал, который использует комбинацию Gatsby, Contentful, Netlify и Algolia в качестве альтернативы традиционной CMS для сайта документации.


Еще интересные публикации


Edison
Изобретаем успех: софт и стартапы

Comments 54

    +7
    Вот вас послушают, а потом такое случается: vk.com/wall-154430577_467
      +2

      Использование Jekyll вместо WordPress не сделает автора мультимиллиардером

        +2

        Автор рекламирует JAMstack на Medium. Смешно.

          +9
          Итак, появился молодой преуспевающий программист. (Хорошо, это был я.) Я решил, что вместо хардкода массива всех букв будет проще написать цикл for, который проходит от 65 до 90, а затем генерировал буквы по полученному коду символа.

          Угу… А потом появился менеджер и сказал, что эта лабуда должна ещё поддерживать русский, греческий, финский и ещё полсотни разных языков.
            +2
            Или не появился. Или появился, но не сказал. Или появился, сказал, но что-то другое (что проект закрывается, например).
              +2

              Ничего страшного. Берем и пишем шаблонизатор, который будет заниматься кодо (бредо?) генерацией.
              Действительно — наличие в коде магических констант вида "код символа А в русской раскладке" ничем не лучше полностью определенного массива. Главное — комментарии в коде не забудьте, которые будут говорить ЧТО МЫ видим перед глазами и ДЛЯ ЧЕГО это было сделано.

                0
                А потом появился менеджер и сказал, что эта лабуда должна ещё поддерживать русский, греческий, финский и ещё полсотни разных языков.
                Или сказал, что Q и O слишком похожи, потому давайте уберем одну из этих букв.
                +2
                Бородатая байка с просторов сети

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


                Родственник мой, S., оказался в Америке в начале восьмидесятых, в
                возрасте "за сорок" и владея английским языком в рамках "средней школы
                давно". Помыкавшись некоторое время (не о том сказ), S. нашел отличную
                работу — программистом Больших Шкафов для телефонного гиганта AB&C
                (кто знает, тот поймет). Для общения с начальством новоиспеченный
                программист быстро выучил английскую фразу "летмишоую" (сейчас покажу),
                за которой следовала демонстрация работающего кода, и вопросов больше не
                возникало.


                Работа в телефонных гигантах неторопливая, но S. бездельничать не любил,
                и решил заняться оптимизацией. В одном из Больших Шкафов обнаружилась
                база данных, а в ней — таблица с парами чисел: 1-3, 2-6, 3-9,…,
                1000000-3000000. Ничтоже сумняшеся, S. таблицу стер, а обращения к ней
                заменил строчкой B=Ax3. Шкаф, радостно заурчав, продолжал
                функционировать. Отсутствие таблицы начальство заметило (и то по чистой
                случайности) через неделю. Состоялся знаменательный диалог:


                • Где таблица?
                • Таблица не нужна.
                • Как это не нужна?
                • Ну, не нужна. Летмишоую. Вот: B=Ax3
                • Что это?
                • Вместо таблицы.
                • А где таблица?
                • Я ее стер. Не нужна.
                • Как стер???
                • Летмишоую. Вот, работает. B=Ax3
                • Ну, работает. А где таблица-то?

                  В конце концов, проявив завидную корпоративную мудрость, начальник
                  оставил S. в покое. А по AB&C долго ходили легенды о сумасшедшем
                  бородатом русском, который ПРИДУМАЛ ФОРМУЛУ.

                Всё движется по кругу...

                  0
                  программистом Больших Шкафов для телефонного гиганта AB&C

                  кто знал и понял поделитесь пожалуйста своим знанием и пониманием
                    +6

                    AT&T, очевидно же

                      +1

                      Было неочевидно, что это просто такое сокрытие гиганта. Я думал, может у них там специфические Большие Шкафы, полные мемов были

                    +4
                    А потом оказалось, что внезапно, чтение из памяти выполняется гораздо быстрее, чем чтение + дополнительные вычисления, и из-за действий «бородатого русского придумавшего формулу», критично важная система, работая в том же режиме, начала испытывать на 50% большую нагрузку. И таблица там изначально была не просто так.
                      +17

                      Запросто. А могло оказаться, что сэкономленная память позволила не устанавливать рядом очередной Большой Шкаф и компания сэкономила пару миллионов долларов.
                      Вывод банален — каждый конкретный случай нужно рассматривать индивидуально, и не агитировать за универсальные практики — "все сворачиваем в формулы" или "все выносим в константы". Всегда найдется куча исключений...

                        +1
                        Еще один вывод — все необычные решения стоит подробно коментировать. Чтобы разнообразные молодые преуспевающие не лезли слепо улучшать.
                        +5
                        Мы можем получить B или чтением из памяти, или вычислением (а не чтением и вычислением).
                        Чтение из памяти быстрее, чем две операции на CPU (сдвиг и сложение)? Не верю.
                          +2

                          Маловероятно (учитывая, что умножение на 3 – это просто 2 сложения). А на современных процессорах вообще гарантированная экономия времени (кэш!).


                          Могло быть другое: где-нибудь в середине таблицы последовательность чуток меняется. Но, надеюсь, он проверил это.

                            0

                            Он не проверил, не будет ли последовательность меняться в будущем

                              0

                              А вот для этого случая он ситуацию как раз улучшил: в короткой формуле увидеть изменение проще, чем в длинной таблице.
                              (хотя при достаточно серьёзном изменении придётся вернуться к таблице).

                          +11
                          image
                            0
                            Знаю другую версию байки, в ней речь не о большом шкафе а о маленьком маленьком чипе, вобщем в итоге в продакшене чип начал перегреваться из-за дополнительных вычислений.
                              0
                              Перегрев из-за операции целочисленного умножения? Вот правда? Переход по индексам массива в памяти гораздо лучше? Ну разве что процессор был совсем доисторический и не поддерживал умножения.
                                +1
                                это ж блин байка, т.е. все мы считаем байкой, а вот то что было целочисленное умножение принимаем за факт? Может там таблица факториалов была от 10**1000 до 10**2000
                                  0
                                  И даже в этом случае х3 превращается в два сложения компилятором.
                            • UFO just landed and posted this here
                              +4
                              есть много доказательств того, что программное обеспечение ест мир.


                              Наверное, это — опечатка. Но, звучит, как народная мудрость.
                              • UFO just landed and posted this here
                                  +1

                                  И братья сестры Вачовски, пророки его

                                    +1
                                    Сестратья
                                0
                                В «нормальных» языках можно делать примерно так: ('A'..'Z').to_a и «закэшировать» в константу.
                                  +2
                                  Тру разработчик написал бы webpack лоадер/плагин, что генерировал бы данную последовательность на этапе сборки и генератор d.ts файлов с описаниями типов в придачу. Вида
                                  Заголовок спойлера
                                  type Letters = ("A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z")[];
                                  

                                  0

                                  Пример вообще забавен: скармливаем его wc и видим 73 символа для генерации константы длиной 28 символов (26 букв и кавычки). Хотя по большому счёту тут пофиг, какое решение использовать, 99.99% это не узкое место.


                                  А так – неплохо бы разработчику иметь опыт в разных областях (и, желательно, базовое образование в CS – можно просто книжки почитать, до уровня "уметь оценивать O(n) и выносить инварианты из цикла"). Например, поиграв с кодогенерацией в C++ или ещё чем – привыкаешь делать то, что можно, в Compile Time.

                                    0

                                    Со стороны пользователей мобильных устройств не хотелось бы тратить заряд батареи на такие вычисления :)

                                    –1
                                    Я один из своих pet-проектов пишу на тяжеловесной Java (под Tomcat) — производельность ну так себе и ресурсы ест хорошо, студент еще *овнокодит помогает. Но на этапе релиза запускаю маленький скрипт с ботом (wget) который обходит все страницы (пара десятков тысяч), сохраняет их в папку, меняет пути и ложит на сервер под nginx (посредством rsync). Взаимодействие с базой на ajax. Сервер самый что ни на есть дохлый, но всё летает.

                                    Имхо, на WP без динамики можно делать тоже самое: работать в локальном WP, а на сервак загружать статику.
                                      +1

                                      поздравляю, вы тоже сделали себе JAM stack. Только J у вас означает Java, а не Javascript

                                      +4
                                      Повторюсь
                                      image
                                        0
                                        Второе можно создать копипастом, но вдруг нам понадобится заменить везде звзедочку на другой символ. Хотя, для сильно спец. символов в такой простой проге есть Ctrl+H.
                                          +1

                                          Думаю легенды обошлись бы одним вызовом, а не пятью :)

                                            +1

                                            … и это был бы вызов puts()

                                              0

                                              К слову, gcc и clang даже на -O1 догадываются преобразовать printf с тривиальной форматной строкой в puts. Но, почему-то, не MSVC.

                                          +6

                                          А если начнёте работать с русским языком, то выяснится ещё одно преимущество хардкод-таблиц — возможность задать свою сортировку. Потому что буква Ё в юникоде находится не между А и Я, а в сторонке (причём в разных сторонках для строчных и заглавных). Такие дела.

                                            +2

                                            А потом попросят добавить фонетическую сортировку в Японском и желание писать "свои" сортировки с хардкод-таблицами куда-то пропадёт :)

                                              +2

                                              Вот тогда-то самое время будет изучить unicode collations и всю связанную машинерию :-)

                                            +7
                                            Миллениалы опять изобретают constexpr?
                                            А если ещё и до «Premature optimization is the root of all evil» додумаются, то вообще страшно становится, можно же будет писать и так и эдак, в зависимости от ситуации.
                                              0
                                              Это не выглядит так, как будто алфавит будет отличаться от одного сеанса к другому.

                                              Сначала подумал, что опять английское "it doesn't look like" перевели дословно, полез в оригинал, а там "it wasn't as if".


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

                                              • UFO just landed and posted this here
                                                0
                                                статья классная
                                                  0
                                                  Статью прочитал, чтобы написать этот комментарий и задать вопрос. Что в статье относится к веб-дизайну?

                                                  Only users with full accounts can post comments. Log in, please.