Как стать автором
Обновить

Комментарии 134

Полностью соглашусь!
О производительности нужно думать на этапе продумывания архитектуры. Вспомните Создателя — он придумал птицам, в числе прочего, трубчатые кости. Не стал их высверливать, увидев, что опытный экземпляр птицы способен лишь подпрыгивать, а придумал и сделал сразу )
Поэтому нельзя, проектируя аппарат передвижения по воздуху, “просто подкрутить что-то, или добавить памяти/ядер”, чтобы корабль стал самолетом. Не взлетит.


И ещё — посмотрите, как отличаются в фармакологии этапы создания препаратов, эффективные in vitro и in vivo. Между ними — «дистанция огромного размера». В инженерии все очень похоже — если опытный экземпляр с трудом оторвался от земли — то, чтобы серийный безопасно летал — нужно затратить ещё 10*X усилий. Поэтому если тестовая версия софта с трудом укладывается в требования по производительности — это не только не повод для радости, но и означает, что исходно требования по производительности не были «встроены» в архитектуру, и если кардинально ничего не поменять — то прод их гарантированно провалит.

С вами не согласты теория эволюции и экраноплан ;)

Если у Вас есть бесконечное время, бесконечный бюджет, и бесконечная энергия — можно, конечно, превратить рыбу в птицу, внеся стохастику в модель наследования, функцию штрафа за ошибку, и самому наблюдать, просто покуривая в сторонке. Но в условиях ограничений приходится интенсивно впрыскивать внешнюю информацию в модель системы, чтобы сократить количество итераций ;). Что касается амфибий и прочих межсредовых комбинаций — оно не может быть одинаково эффективно в обеих средах так, как это делают нативные организмы или устройства. Поэтому в естественной среде (эволюция), или искусственно-организованном выживании (война) амфибии неизбежно вымрут

Эволюционная разработка то ли это что хочет заказчик? Типа отдам разработку трем мутантам и кто выжевет? Оптимизация на начальных тапах проектирование может быть практически бесплатной. А вто нет. Давайте запилим на PHP+Mysql а там может не взлетит и заказчик не догадается почему не взлетело.

НЛО прилетело и опубликовало эту надпись здесь

Насчёт экраноплана не скажу, не в курсе. А вот с эволюцией ситуация такая, что кости были с пустотами ещё у динозавров. И судя по всему даже у предков динозавров.

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

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

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


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

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

Вообще, нет, не сразу. Это как раз побочная фича. Боженька сначала сделал архозавров, которые, оказавшись удачными доминирующими видами, стали основательно отжираться и расти в размерах, и возникла проблема облегчения тушки, чтобы оно не сломалось. Тогда боженька стал смотреть, где можно что выкинуть, и придумал пневматизацию костей, ну т.е. чтобы эти здоровые кальциевые штуки были не цельными, а с воздушными полостями внутри. Получилось неплохо, тушки до 20 метров стали отрастать. Заодно, чтобы мелкие тушки не замерзали (у крупных проблема терморегуляции сама собой решилась), боженька добавил им пуха, перьев всяких. Получились динозавры. Но потом они согрешили как-то, и боженька наслал на них потоп меловое вымирание, и все крупные виды померли. А мелкие, они вдруг открыли сайд-эффект полученных фич:
а) облегчённые тушки
б) оперение для маневрирования
И стали с их помощью сначала эффективно драпать/прыгать с деревьев от начинающих наглеть синапсид. А потом прокачали скиллы, и стали летать. Так что нет, птички, это когда старая фича нашла новое применение.

читал как увлекательный триллер! Пишите еще!

Могу я написать? На дня появилась идея и не знаю вот с кем обсудить.
Думал про "что было первее — курица или яйцо", почитал в сети и оказалось, что точно не установить. Но зато появились мысли как могло появиться яйцо любого существа, необязательно курицы или динозавра.
Выкидыши во время беременности случаются у всех существ во все времена, даже бывают дефекты в генах у женщин, увеличивающие их частоту.
Так вот, когда-то у какого-то беременного существа на каком-то сроке случился выкидыш. Ничего необычного, но плод не только выжил, но потом смог оставить потомство, беременность которого тоже закончилась выкидышем и выживанием потомства — фича закрепилась.
Что это дало? Немного сократился срок беременности, т.е. беременное получило небольшое преимущество в том, что может чуть меньше обременяться беременностью и заниматься другими важными вещами — выживать и искать партнёра, чтобы снова забеременеть.
Почему же плод выжил? Скорее всего, он доразвивался до обычного новорождённого из-за питательных веществ, которые остались либо в маточной слизи, либо в нём самом.
В итоге круг оптимизации сформировался — стало выгодно оставлять всё больше питательного для плода, чтобы "выкидывать" его на всё более ранних сроках, чтобы быстрее освобождаться для выживание и новой беременности.
Одновременно с всё меньшим сроком развития и всё большим запасом веществ росла и защита плода — чаще выживали те, кто рождался с всё более прочной покрывающей слизью, а потом и твёрдой оболочкой с нужной формой. Внутренним органам будущей курицы тоже пришлось меняться, чтобы легко выводить уже не мягкое тельце, а всё более твёрдый предмет покрупнее.
Таким образом, вполне сформированное новорождённое животное со временем деградировало назад до предела — в "бульон" из питательных веществ-материала внутри твёрдой оболочки, в беременность вне тела.
Как философия Unix — пусть программа делает только одну вещь, зато хорошо. Предкам курицы оказалось неудобно выживать "с животом" и они разделились.

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

Не говорю — у каждого существа свои условия жизни и свои способы эффективности.
А икринки как могли возникнуть? Делилась клетка и вторая эволюционно не развивалась?

Думал про «что было первее — курица или яйцо», почитал в сети и оказалось, что точно не установить.

В смысле? Взрослый организм изменяться уже не может. Так что однозначно яйцо.

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


Если принять, что яйцо годится любое, тогда почему нельзя принять и любую курицу?


Если внести уточнение — «курица или куриное яйцо» — задача не имеет решения. Эволюция (постепенное ползучее изменение облика от поколения к поколению) идёт настолько медленно, что невозможно найти чёткую грань между «пракурицей» и «курицей».
https://ru.wikipedia.org/wiki/Проблема_курицы_и_яйца
Тогда что мешает так же родиться курице из яйца, которое нельзя классифицировать как куриное?

То, что яйцо — это уже курица. Зародыш курицы, если быть совсем точным.

-Что было первее — яйцо или курица?
-Яйцекурица!


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

Курица могла родить цыплёнка в плёнке — первый вид яйца.

Эм, предки куриц вплоть до динозавров/рептилий сносили яйца, какие плёнки?

Эта фраза разве относится конкретно к курицам? Она относится к первым существам, способным откладывать яйца. Первые динозавры или их предки откладывали яйца с мягкой оболочкой: https://in-space.ru/myagkie-yajtsa-perevernuli-predstavlenie-ob-evolyutsii-dinozavrov-i-gigantskih-reptilij/

Откуда в вопросе «Яйцо или курица» появились первые яйцекладущие?

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


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

Почитайте как работает эволюция. Сразу вопросы отпадут.

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

Какой момент вас смущает?

Меня как раз ничего не смущает.


Яйцо как способ размножения появилось намного раньше кур.

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


Отсюда станет очевидно, что первое яйцо с зародышем курицы отложила "недокурица".

Что по вашему "курица"?
Чем ещё она, вырастив из этого яйца, должна отличаться от "недокурицы"-родителя, кроме как способностью кладки яиц?


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

Это обычная языковая проблема. Если начать формализовать её, то решение без проблем найдётся. Но из-за неоднозначности человеческих языков формализовать её можно множеством разных, порой противоречащих друг другу способов. И я не вижу смысла обсуждать подобную проблему вообще, только разве что у вас куча свободного времени. Я беру первое решение из Википедии, основанное на знакомых мне вещах, и объявляю его истиной в последней инстанции. Всё одно это не хуже бесконечного словоблудия, что я тут написал по пустяковому поводу. Наверное у меня много свободного времени. А точнее просто высокая температура. Прости, Хабр.

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


Эволюция (постепенное ползучее изменение облика от поколения к поколению) идёт настолько медленно, что невозможно найти чёткую грань
Это я и называю словоблудием, все эти пракурицы и праяйца.

Это какого создателя? Рода, Брахму, Ади Шакти, Саваофа?
Кто из них трубчатые кости придумал, я что-то запутался :)

Посмотрите в Патентном бюро.

Главное чтобы к тому времени как «супербыстрое и оптимизированное приложение» вышло на рынок, оно не превратилось в Неуловимого Джо.

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


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


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


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

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

П.С. шутки над производительностью PHP уже малость устарели.

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

Надо снять пару роликов, как стартуют студии от 6.0 до самой современной. Пользователи охренеют..

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


А я сам как-то запустил фотошоп 7.0 на современном компе и просто обалдел — он запускается как пейнт, но в нём есть 80% функциональности современного фотошопа, как так вообще?

Просто те 20% функциональности, что отсутствовали в ранних версиях — отсутствовали во многом потому, что требуют гораздо большей производительности.
Достаточно посмотреть на какой-нибудь нейросетевой super resolution фильтр — требует гигабайты места, на каждую картинку без мощной видеокарты уходит минут по 20 — но качество несравнимо по сравнению с любыми lanzcos и иже с ними методами увеличения разрешения.
То же и со студией — всякие подсветки, проверки, анализы кода и иже с ними, которые очень помогают в работе, как раз и замедляют работу. А стоит поставить какую-нибудь Express-версию, в которой это всё отключено — и всё летает.

Подсветки, проверки и анализы когда и тогда тоже были, и можно задать логичный вопрос — почему они работают в момент шагания в режиме отладки? Но нет, там проблема совсем в другом, не в том, что там какие-то особенно сложные 20% функциональности навернули. Просто при разработке придерживаются другого подхода — "а? Тормозит? А давайте его асинхронно зафигачим. Когда-нибудь (eventually) допроцессится и тогда и отобразим результаты" и вот так весь современнный софт и работает — хрен поймёшь, отреагировал он на нажатие кнопки или нет, что там внутри происходит, всегда ему надо дать "настояться", чтобы там вся эта "когда-нибудь" машинерия провернулась.

Быть то они были, но там тоже произошли качественные улучшения — которые отнюдь не бесплатные.
И в режиме отладки свои анализаторы, которые также выполняют полезную работу, вроде вычисления значений кастомных переменных или показа результата выполнения какого-то нетривиального геттера в классе.
Отладка сейчас и отладка десяток-другой лет назад сильно различаются.

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

Всё дело в том что "этим местом" обычно оказывается весь проект. Пол миллисекунды времени загрузки конечно не стоят того чтобы корпеть над ними пол года, но пол секунды времени загрузки страницы или выполнение какой-то основной операции вдвое быстрее — стоят.


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


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

SaaS продукты потом таки переписывают отламывая по кусочкам сервисы от монолита на PHP или Руби (почему-то, очень многие начитают именно с этих языков).

но пол секунды времени загрузки страницы или выполнение какой-то основной операции вдвое быстрее — стоят

Да вот непонятно, стоят ли? Что это ускорение даст продукту? Какую из поставленных целей на месяц/квартал/год это ускорение поможет достичь? Можем ли мы измерить результат этого ускорения не в милисекундах, а в бизнес показателях?

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

Конечно, ещё гугл пятнадцать лет назад намерял, что каждые 100мс замедления страницы уносят определённый процент пользователей. Просто тогда они вынуждены были конкурировать и сами создали культуру и ожидания, что поиск будет открываться мгновенно, а в других областях такого не случилось и после выживания определённого продукта в каждой из областей — на них перестаёт оказываться давление в сторону ускорения — а куда ты денешься, чо аналоги есть что ли?

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

П.С. я отталкивюсь от понимания того что термин «оптимизация» это не только Производительность, но и архитектура приложения по фен-шую

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


Я думаю ваша позиция имеет смысл когда продукт — технический, например, база данных или фреймворк (типа, MongoDB). В других случаях, тайм-ту-маркет или нет, продукт может быть просто плохим вне зависимости от производительности, но это к оптимизациям не сильно относится.

Я все же придерживаюсь вот этого «Мы создаем программы сначала правильными, а потом — производительными.»

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

И если следуя из моего опыта, так или иначе придется позже заняться производительностью, то какой смысл заниматься этим на ранних этапах? Бесмысленно. Лучше сделать быстрее рабочий вариант, с минимвльным набором функционала, что бы погонять на реальных данных, и в реальных условиях, которые могут значительно отличаться от того, что у вас в голове, чем сразу придумывать супер пупер оптимизацию. Как то в одном проекте видел такую ранюю оптимизацию, кэширование PreparedStatement, больше человеку в голову не пришло. Типа улучшит производительность, ага. А после написанные SQL запросы, этим же человеком отрабатывали по минуте или две. К чему было тратить время?

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

Плюс «оптимизированный» код труднее отлаживать. Неоптимизированный выглядит проще, проще в нем разобраться. Уж правда, лучше сначала сделать все рабочим, что бы удовлетворяло требованиям, чем супер быстрый код, но не работающий как ожидается.

Как говориться — пусть многие поступают как вы написали, там ценнее я буду как специалист, который сначала думает о производительности, а затем пишет правильно!
В самом деле — это же не может быть противоположностью.
Конечно, надо заранее думать о производительности, и соотвественно выбирать инструменты.

Речь не идет о том, чтобы «не думать о производительности». Речь о том, что в процессе разработки сначала «правильно», потом «быстро».
В противном случае будет тратиться время на оптимизацию «неправильного» кода.
«Неправильным» код может быть по нескольким причинам — ошибки в разработке (баги), ошибки в требованиях (аналитик не понял заказчика), ошибки в архитектуре (например, выбранные технологии не могут быть использованы заказчиком в силу ограничений законодательства).

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

Я и говорю, главное выбрать правильный инструмент. Есть какие то паттерны под разные задачи, в том числе и по требованиям к производительности. Как к примеру C/C++ для каких ни будь микроконтроллеров или где требуется фиксированная скорость выполнения операций. Так же я не буду использовать какой ни будь RabbitMQ, если мне нужно передать всего 300 сообщений за день, я возьму что то попроще. Было бы глупо использовать один и тот же паттерн под разные требования по производительности и потом пытаться его оптимизировать. Ясно что должны быть какие то прикидки заранее.

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

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

Так можно писать код так, что он будет просто "рыхлый" — открываешь профайлер, а там ровным слоем размазано. Почему? Ну можно посмотреть на какие-нибудь дикие Java колстеки на сотни функций глубиной :)

Как и на c++ написать вполне годный код, который ниразу не кэш-фредли, и привет тебе равномерно медленный код. Правда тут проблемка в том, что не будучи близко к сеньорству, разобраться, почему так происходит, очень сложно. Для этого и нужен код ревью, просмотр asm кода. Как мы понимаю вчерашнему джуну это будет даваться сложно. Если он будет постоянно думать о таком, то вообще ничего не напишет. Тут нужен опыт.

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

Прежде всего — это довольные клиенты/пользователи.

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


Для аналогии — есть бригады строителей, которые делают просто плохо, потому что не могут по-другому. Но естественно, они никогда не признаются в этом ни клиенту, ни себе, будут говорить — "да это просто платят мало, сроки ставят такие, приходится делать тяп-ляп, рынок такой", но в реальности, сколько им не заплати, просто нет нужного класса, нет профессионализма. Вот и в разработке тоже самое — есть люди пишушие такие вещи как https://spdk.io/ или simdjson и есть люди, которые пишут экран загрузки GTA.


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

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

Пока не произойдет следующее:
— самочки начнут давать предпочтение куликам, которые больше всех скопили еды;
— кулик захочет, расширить свою территорию на другие болота, что бы получить больший доступ к самочкам, а там свои предпочтения;
— с соседнего болота привалят кулики, которые перехватывают самочек в водухе, и делают свои дела и не запариваются с выращиванием потомства.

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

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

Резюмиру.
У индустрии есть 2 локальных проблемы:
— решение задач которые, нафиг никому не нужны;
— плохо решенные задачи, которые создают слишком много проблем в будущем.

Идеальный код, никому не нужен, кроме самого разработчика. Есть пользователи, которым нужен быстрый код; есть те которым нужен красивый интерфейс; есть те, которым на все плевать главное, что бы батарейки до вечера хватало. А решать задачу про сферического коня в вакууме, это к перфекционистам. Пока они будут вылизывать код, я буду смотреть на довольных пользователей и банковский счет. Пока идеалистам не захочется кушать, ведь они не продали свой продукт, потому что он не идеален.
Точная цитата Кнута
Another important aspect of program quality is the efficiency with which the computer's resources are actually being used. I am sorry to say that many people nowadays are condemning program efficiency, telling us that it is in bad taste. The reason for this is that we are now experiencing a reaction from the time when efficiency was the only reputable criterion of goodness, and programmers in the past have tended to be so preoccupied with efficiency that they have produced needlessly complicated code; the result of this unnecessary complexity has been that net efficiency has gone down, due to difficulties of debugging and maintenance.

The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.

We shouldn't be penny wise and pound foolish, nor should we always think of efficiency in terms of so many percent gained or lost in total running time or space. When we buy a car, many of us are almost oblivious to a difference of $50 or $100 in its price, while we might make a special trip to a particular store in order to buy a 50 cent item for only 25 cents. My point is that there is a time and place for efficiency; I have discussed its proper role in my paper on structured programming, which appears in the current issue of Computing Surveys

Это заявление вовсе не про то, что оптимизацией можно заняться потом. Оно о том, что время программистов дорого. И нужно трезво оценивать стоит ли тратить своё время на вылизывание кода и стоит ли оно того. Если оно того стоит, то вылизывать нужно сразу. А если оно того не стоит, то у программиста никогда не будет свободного времени на рефакторинг никогда. Работодатели не дураки, чтобы впустую сжигать свои деньги.

Я не читал текст, из которого взята цитата (возможно, ответ там), но непосредственно из цитаты не могу понять, откуда вы берёте утверждение про "вылизывать сразу" и никогда "не будет времени на оптимизацию". Не могли бы вы пояснить? Спасибо!

откуда вы берёте утверждение про «вылизывать сразу» и никогда «не будет времени на оптимизацию»

Это уже отсебятина.

Да, спасибо. Ну что ж, наши с вами интерпретации текста Кнута не совпадают.

Я бы сказал, что этот отрывок тоже не отражает контекста.
Кнут работал на уровне ассемблера.
Т.е думаю его слова сейчас напрямую относятся к разработчикам на Adruino или STM32 или чем-то подобном, т.е. малым встраиваемым системам.
Действительно когда кодируешь под микроконтроллер все время стараешься писать наиболее быстрые алгоритмы. Это как навязчивая мания, когнитивное искажение.
Потом оказывается что тормозит вовсе не то, что отняло столько внимания.
Но избавиться от него невозможно даже отлично зная советы Кнута, потому что есть что-то в психике.
Т.е. Кнут высказал не рекомендацию, а отметил медицинский факт.
Люди не перестанут ехать на другой конец города в другой магазин ради экономии пары центов.
Как то, вначале 2000-х писал программку для спутникового ресивера, который на встроенном линуксе работал. Надо было картинки отображать, а хранились в виде массивов, прямо в коде. Я там заморочился оптимизацией и решил картинки хранить в сжатом виде и потом разжимать для отображения. Встроенной памяти было немного. Неделю только на это убил, так гордился. А потом оказалось, что все и так заливалось в cramfs, где все сжималось и смысла в моей «оптимизации» не было.

А как насчёт другой цитаты из того же текста:


The improvement in speed from Example 2 to Example 2a is only about 12%, and many people would pronounce that insignificant. The conventional wisdom shared by many of today’s software engineers calls for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being practiced by penny-wise- and-pound-foolish programmers, who can’t debug or maintain their “optimized” programs. In established engineering disciplines a 12% improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering. Of course I wouldn’t bother making such optimizations on a one-shot job, but when it’s a question of preparing quality programs, I don’t want to restrict myself to tools that deny me such efficiencies.

Это в 1974 году. С тех пор речь идёт о 10х или 1000х оставленных на волю случая.


image

Как жаль, что мы живём в мире где нет библиотек на Си, в которых проделаны все возможные оптимизации. Как жаль.

НЛО прилетело и опубликовало эту надпись здесь
Я считаю эту логику ошибочной. Если ваша программа все еще является прототипом и выполняет, например, 1% (20%, 50%, 90%) того, что она должна делать, и она уже работает медленно, то она будет еще более медленной после того, как вы ее закончите, разве нет? Если вы заставите ее делать больше, почему он должна стать быстрее?


Мне кажется что проблема тут. Прототип нужно выкинуть и начать писать программу «как надо», а не пытаться оптимизировать изначально плохую архитектуру.

Наверное, зависит от размера прототипа. Но в моей практике действительно первый код часто выкидывается, и пишется заново, причём скорость написания во второй раз выше минимум на порядок.

Забавно, тоже занимаюсь в основном графикой, и ровно та же ситуация.
Преждевременная оптимизация — зло.
Слишком поздняя оптимизация — зло.
Несвоевременная оптимизация — зло.
Слепое и догматическое следование любому принципу, включая этот — зло.
… и?

Идеализм — зло

Возможно автор в словосочетании «преждевременная оптимизация» не понял первое слово.

Проблема в том, что часто от создания действующего макета до итогового продукта всё значительно меняется несколько раз (например, оказывается, что в реальной жизни тут не одна сущность, а пара, в отношении 1-к-многим). И каждый такой раз есть вероятность, что преждевременная оптимизация:
1. Будет усложнять корректировку под изменившуюся задачу.
2. Будет выброшена на помойку.
Вот вечно из одной крайности в другую…

Речь идет о том, что пока не просматривается конечная форма продукта, со всей его окончательной функциональностью — нет смысла оптимизировать отдельные части. Ровно потому, что любая из них может быть или переписано заново и принципиально, или вообще в окончательный вариант не войти! На кой черт ее тогда «оптимизировать»?

Это конечно не значит, что не нужно думать о производительности совсем — можно и нужно, но исходя из знаменитой формулы 80/20 и здравого смысла…

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

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

В случае же выбора JS/C++ — то это уже не про оптимизацию кода, а про выбор инструмента. А инструмент выбирается под задачу исходя из многих вводных.

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

Не знаю насчёт обычных приложения, а вот для игр правило простое:
прототип должен иметь производительности ровно столько, чтобы её было достаточно для отладки — чтобы тестировщики и разработчики на своём (топовом!) железе не мучались из-за этого — и ни на йоту больше.
Сделать больше — и художники, моделлеры и левел дизайнеры сразу насуют столько дополнительных элементов и полигонов, что никаких резервов производительности не останется — из-за чего попытка оптимизировать для слабого железа вроде старых консолей превратится в ад.
чтобы тестировщики и разработчики на своём (топовом!) железе не мучались

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

И что это даст?
Получится игра, расчитаная на «среднее» железо, которое к моменту выхода ещё и устареет поколения на 3 — и все будут плеваться на ужасную графику.

Производительность оставляют на потом, но "потом" часто не случается, так как нужно пилить новые фичи и времени на переписывание нет (и дорого это).


Поэтому масштабируемость нужно сразу закладывать на этапе проектирования. Что не нужно делать — так это заниматься оптимизацией каждой отдельной небольшой функции, есть и такие любители.

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

А потом получается, что кому-то легче тесты разбить на группы и распараллелить чем сделать так, чтобы запрос в базу не длился по 12 секунд на тестовом наборе данных. Я не программист, но не верю что это «нормально». А для кого-то это «нормально». Однако «нормально» и «я не знаю как это исправить» две разные вещи.

Вот еще история.

Мы как-то писали новый набор тестов, и выпытали у разработчиков, что у приложения есть API, и получается, в тех тестах, где создание бизнес обьекта через формуляр не является предметом теста, его можно создавать через вызов API, вместо UI, и экономить 20 секунд в каждом тесте. И молодой автоматизатор сказал: «Да какая разница, оно же все равно ночью на сервере работает. Вот когда за 8 часов перевалит тогда и будем думать.» Я, в педагогических целях, ответил, мол, ну, ладно, давай так, посмотрим.

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

Так задачи по оптимизации времени исполнения, быстро, как пузыри в джакузи, поднялись в беклоге и были вставлены в ближайшие спринты. И все остались довольны.

А как насчет легаси проекта объемом в 7 млн строк? Когда его писали, то наверное думали об оптимизации и производительности, вот только те люди были не боги и получилось у них не то, чтобы прям плохо, но и не супер пупер. А после тех людей были другие люди, которые писали свой код, который решал задачи и добавлял новые фичи, но который проблемный только в каких-то крайних случаях (типа больше 1000 объектов на листе), а были еще и студенты из программы GSoC, которые вообще про оптимизацию и производительность никогда не слышали. И теперь мы имеем проект, который есть где оптимизировать именно в производительность, только вот людей нету (ну или денег, что одно и тоже в нашем случае). Однако при этом проект вполне рабочий, весь мир юзает и не жужжит (хоть и плюется от багов периодически).
Я это к тому, что вообще возможно ли в огромных проектах оптимизировать производительность сразу?
На мой взгляд, как тут уже писали, нужно сначала продумать архитектуру. Вот на этом не следует экономить. Если архитектура позволяет, то разделить бизнес логику и производительность (условно говоря выбранный метод сортировки). А потом уже добавлять мясо (бизнес логику) и когда упремся в производительность, заменить «метод сортировки».
По-моему, тут не о чём спорить.
Мой вывод таков: если вы хотите создать действительно быструю программу, с самого начала обращайте внимание на производительность.

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

Как обычно — кто-то в интернете что-то написал. А потом народ пытается это опровергнуть или подтвердить, пока настоящие синьоры пишут код и решают проблемы )
А если серьезно — автор неправ. Конечно, лучше работающая программа, но медленная, чем быстрая, но некорректная. Поэтому лучше сначала разработать прототип, а потом уже понять — где узкие места и их отрефакторить. Тем более, что уже будут нормальные тест кейсы и понимание области применения и ожиданий пользователя

Хотел откомментировать корневой пост, но Ваш комментарий, в принципе, передаёт и мои мысли.


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


Кстати, по поводу скорости. Вообще говоря, а как вообще понять что программа тормозит? Нужны метрики скорости для начала. Очевидно, чтоб добавить такие метрики нужен некий готовый код. Возможно, самая наивная реализация будет достаточно быстра для типичного использования. Так зачем напрягаться?


И не забываем про принцип Парето. Оптимизировать имеет смысл только самые «горячие» участки кода.


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

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

Чтобы правильно оптимизировать, нужно нырнуть в будущее и увидеть, какие фичи вы добавите и как твоим решением будут пользоваться пользователи, иначе ты выкинешь свое время в мусорку на оптимизацию совсем не узкого места, а то и хуже сделаешь. Например, накинешь кучу ненужных индексов в базу, замедлив вставку. А ты знаешь, какие данные будут в будущем в бд? Не совсем. Возможно, будет достаточно 1 индекса и он будет супер селективным.
Но забивать на производительность в очевидных местах — тоже неправильно.
Мой вывод — нужно знать меру и не уходить в крайности

Если ваша программа все еще является прототипом и выполняет, например, 1% (20%, 50%, 90%) того, что она должна делать, и она уже работает медленно, то она будет еще более медленной после того, как вы ее закончите, разве нет? Если вы заставите ее делать больше, почему он должна стать быстрее?

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

Производительность же почти всегда определяется заложенной архитектурой и зачастую значительное ее улучшение представляется приличной проблемой.
Итак, у нас вопрос — когда же оптимизировать программу уже НЕ преждевременно?
Ответ прост. Надо быть просто умным, и тогда вы сделаете оптимально.
#irony
Без объективных критериев подобные советы почти бессмысленны, а критерии у каждого в голове свои и к тому же все программы разные.
Почему почти? Ну можно переформулировать так:
«Программист! Увидел возможность оптимизации? Не используй её, не дописав программу до рабочего состояния!»

Раз все обсудили, я пройдусь по переводу: "Я говорю, что эти улучшения случайны. Им просто повезло. Они могли никогда не случиться так легко, как раньше". Серьезно? Статья написанная по-английски русским переведена на русский и все равно осталась на английском. Горшочек переводов, не вари! К счастью, целиком перевод с основном нормальный.

Я видел такие программы, которые «сразу были оптимизированы».
Тормозили и глючили безбожно.
Т.к. при «оптимизации» использовалось куча грязных хаков.
Благо FoxPro и Clipper это позволяли.
Которые не давали нормально рефакторить код, без переписывания всего приложения.

ИМХО в начале нужно писать «чистый код».
Только потом, когда программа работает, искать узкие места.
Которые, если код написан «чисто», достаточно легко изолировать и оптимизировать.
«Преждевременная оптимизация — корень всех зол» — это корень всех зол.
Хорошо сказано. Современный софт страдает от ожирения. Точнее, дикого, безбожного ОЖЫРЕНИЯ. Ожирение ведёт к большой куче проблем, которые выходят далеко за рамки производительности (в т.ч. страдает надёжность, функциональность и т.п.). Тонны жира оправдывают «сначала сделаем программу рабочей, потом (никогда) — быстрой». Так что про корень всех зол близко к истине, весьма…
Как уже было сказано, пока вы будете полировать свой продукт, конкуренты уже пару IPO проведут. Когда железки дешевые, а скорость работы программ приемлемая, оптимизация мало кого волнует.
Кагбе мой камент немного про другое, ожиревший софт не может быть качественным…
А что вы имеете ввиду под ожиревшим софтом? Электрон приложения всеми любимые?
ожиревший софт не может быть качественным…

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

Иными словами — куда полезнее было бы чётко определить критерии ожиревшести, качественности и некачественности, чтобы окружающие могли как-то отвечать.
Уходит 6-8 гигов оперативки в простое + несколько вкладок браузера, даже никаких серьёзных пакетов не запущено.
Чем вообще можно занять ГИГАБАЙТ памяти? У меня никакой фантазии не хватает!
Впихивал вебморду железки со всем стеком в ATmega64 (64 КБ ПЗУ + 4 КБ ОЗУ) — да вполне свободненько влазит. Без всяких ассемблеров даже (ну почти). Открывали для тестов сотню вкладок на нескольких компах — работает, с динамическим обновлением по XHR…
Ну ладно, серьёзный софт требует больше ресурсов на несколько порядков. Но я всё равно не понимаю куда можно потратить несколько гигов!
Почему запросы растут по экспоненте, а функциональность — на проценты? А то и вообще серьёзно падает?
А ведь все эти гигабайты непойми какого хлама — явно содержат помимо каких-то непонятных телодвижений ещё значительный процент багов и глюков!

Забавно, что этот аргумент всегда всплывает при обсуждении программных продуктов, но от аппаратных на этом же сайте (на хабре) все требуют, чтобы они были вылизаны, не ломались, право на ремонт, 10 лет запчастей, а иначе это всё копроэкономика и жадные производители. А ведь тем тоже важен тайм-ту-маркет, а то конкуренты обойдут, а пользователи постепенно привыкают к чему угодно — хоть к тормозам, хоть к ломучести, хоть к тому что их будет немножечко током бить при работе за компьютером — откуда они будут знать, что это неправильно, если всё вокруг током бьётся?

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

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


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

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

Категорически НЕ согласен с автором. Очень удивлен, что у статьи столько плюсов. В заголовок вынесен принцип, который очень опасно абсолютизировать, и да, я полностью согласен с Кнутом. Вся суть работы над архитектурой системы — это создание такого рода взаимоотношений между ее элементами, при котором дальнейшая оптимизация каждого, не будет затрагивать остальные. И только после того, как ваша архитектура будет удовлетворять этому требованию — вы можете вкладываться в оптимизацию производительности. Помимо этого, бывают случаи, когда нужно доказать, что задача в принципе имеет решение, или когда точность вычислений важнее скорости. Практически всегда, в моей практике, удавалось решать вопросы производительности в свое время, то есть ПОСЛЕ того, как вы построите основную конфигурацию и протестируете ее базовые параметры. Исключением могут быть только ситуации, когда вся суть вашего решения сводится к производительности. В общем, мне кажется, автор сам не до конца понимает о чем говорит и страдает юношеским максимализмом.
В заголовок вынесен принцип, который очень опасно абсолютизировать, и да, я полностью согласен с Кнутом.

И с тем, что 12 процентное повышение производительности, легко получаемое, никогда не сочтут незначительным, тоже согласны?

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

Вы написали, что полностью согласны с Кнутом, а я процитировал Кнута. С этой цитатой вы, как я понимаю, тоже согласны.

Ну камон, это какое-то агрессивное передёргивание слов оппонента — вполне понятно же, что человек имел в виду.
Ну камон, это какое-то агрессивное передёргивание слов оппонента

Ну нет )). Это агрессивная попытка побудить оппонента прямо сказать, что он с цитатой из Кнута не согласен )).


вполне понятно же, что человек имел в виду

Вроде понятно. Но и позиция того же Кнута, она немного сложнее, чем многие думают. Цитата про 12 процентов, она, кажется на предыдущей странице по отношению к цитате про преджевременную оптимизацию.

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


Впрочем, непонятно, что это перетягивание Кнута на свою сторону даёт любому из оппонентов :)

Впрочем, непонятно, что это перетягивание Кнута на свою сторону даёт любому из оппонентов :)

Я лично надеюсь, что участники дискуссии узнают, что Кнут на самом деле так не думал, ознакомятся с позицией Кнута подробнее и скорректируют свою.

Хотел написать тоже самое, про "категорически не согласен с автором", но вы меня опередили. Я лишь хотел бы немного раскрыть моё (и надеюсь чуть более исходное) понимание фразы, как минимум в двух факторах.


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


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


Во-вторых, это может оказаться банально ненужным, лишняя трата энергии. Если очень условно и притянуто за уши, то вместо пузырьковой сортировки (ну или сортировки вставками) реализовать quick sort. А потом узнать, что размерность сортируемого множества никогда не доходит до тысячи. Или реализовать quick sort множества по запросу (лениво) множества на чтение, но окажется, что записи в целом происходят намного реже чтений, поэтому намного выгоднее может оказаться хранение деревом (особенно, если записи не подверженны изменениям).


Но это сова на глобусе, в реальности проблемы могут быть куда глубже. Что в целом, вполне можно заметить на старых и современных файловых системах — разные проблемы решаются совсем по разному. Или, вот, графический конфейр раньше был блокированный чтобы избежать сложности с конкуренцией (и более быстрыми вызовами, ессно). С развитием многопроцессорных систем это стало атавизмом, который очень сильно замедлил переход игровой индустрии на многопроцессорные (читай, многоядерные) системы.

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

Одному мне показалось странным то, что нигде не сказано о том, что по важность производительности можно узнать у самого заказчика, в самом начале разработки?

Я не вижу никаких проблем ни у себя, ни у окружающих программистов сделать какую-угодно прихоть клиентов:

  • Хотите быстро — пожалуйста
  • Хотите надежно — пожалуйста
  • Хотите производительность — пожалуйста


Проблемы начинаются там, где программистов в первый год разработки только гонят по срокам реализации новых фич, а потом, через год, начинают спрашивать «а почему так много багов?», «а почему все так тормозит?» и у программистов, почему-то, не хватает смелости сказать очевидную вещь: а что хотели, то и получили!

Есть даже такой классический развод «функционал бонусом», когда в ТЗ указано 10 пунктов, а потом, в процессе, заказчик хочет еще 5 пунктов за те же деньги и сроки, и доказывает, что они «само-собой разумеющиеся». Детская разводка, которая, к сожалению, очень часто срабатывает.

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

Пфф, заказчик. Кажется, что автор изначально говорил о массовом ПО (таком, которым мы все пользуемся каждый день или достаточно регулярно) и у такого ПО заказчик — это какой-то размытый образ для разработчиков, переданный им через множество посредников и прокси (а как иначе? Не будешь же ты приводить каждого пользователя и спрашивать его мнение?).


И пользователи, в массе своей, не имеют никаких механизмов, чтобы передать своё недовольство (см. историю с загрузкой GTA Online, когда каждый игрок ждал по несколько минут, а что делать?), если вообще осознают, что может быть лучше (откуда им знать, если всё вокруг одинаково тормозит?). Единственные, кто может поменять положение дел — сами разработчики, изнутри индустрии, они должны оказывать давление на "заказчиков", то есть бизнес, который представляет заказчика и формирует требования к разработке, должны демонстрировать профессиональную гордость и рабочую этику. Но, как вы правильно говорите: почему-то не хватает смелости сказать очевидную вещь.


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


А вообще, ответная реакция сообщества показательна — "да ничего не тормозит, а если и тормозит, то виноваты заказчики, не требуют чтобы не тормозило, а требуют, но мы их не слышим? Не было такого, да и вообще, раньше работа час выполнялась, сейчас минуту занимает — это же улучшение, ну и что, что она могла бы мгновенно выполняться, дизайнеры прогресс бар нарисуют".

«не буду говнокодить, давайте делать лучше, давайте вносить скорость, отзывчивость в требования, даже если их никто явно не просил»

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

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

это не просто улучшение, в зависимости от проекта это может быть даже симптомом, что вашей команде нечем заняться (надо идти бить продакта и проджекта) или она саботирует приоритеты со стороны продакта (бить всех сразу).

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

Проблемы начинаются там, где программистов в первый год разработки только гонят по срокам реализации новых фич, а потом, через год, начинают спрашивать «а почему так много багов?», «а почему все так тормозит?» и у программистов, почему-то, не хватает смелости сказать очевидную вещь: а что хотели, то и получили!


Подписываюсь. По моему опыту заказчикам на первых этапах разработки очень сложно решиться разменять время разработчиков на более качественную работу. Работу с требованиями, работу над разработкой решения которое будет не таким лобовым и тормознутым. Конечно, со стороны заказчиков тоже есть причины, по которым они и делают этот выбор. Но это удивление, в определенный период жизни проекта, когда вылезают минусы принятого раннее решения — выглядит по-детски.
Производительность главнее всего
Главнее всего — качество, в котором производительность — одна из неотъемлемых составляющих.
Ну да, давайте сразу писать веб-приложения и продумывать архитектуру под 100 миллиардов пользователей в секунду. Сразу делаем производительное приложение из расчета, что у нас всё население земли будет им пользоваться 24x7 и еще 94 миллиарда инопланетян, которых мы обнаружим
Совершенно согласен с посылом, разве что идея писать сразу быстрый код — лютая крайность. Надо сразу закладывать места для оптимизации и думать, как тот или иной участок можно сделать быстрее. Утрировано: если есть место, где сортируется массив, то можно использовать пузырёк, если так быстрее писать код, но это должна быть легко изолируемая функция, которая легко заменяется.
К сожалению в реальности низкая производительность пробирается в интерфейсы и сервис/класс/функция вообще не могут быть хорошо оптимизированы без изменения API. Вспоминая недавнюю историю R*, если функция-геттер опции конфига получает многометровый конфиг в виде zero-termiated строки, то она не может работать быстро.
Или чуть более C++ специфично. Если объект в метод принимает char* или string_view, то он вынужден копировать эту строку, так как не имеет гарантий на срок жизни.
То есть не надо тратить время на супер оптимизированные алгоритмы, но надо задумываться о том, как их потом внедрять.

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


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

Согласен и с Кнутом и с автором. С Кнутом — что когда создаешь объёмное приложение стремление к идеалу может завести в долгие дебри и проект застрянет надолго. С автором, что в работе никогда не упускать из виду цели на производительность, что на деле представляет из себя другой подход к разработке, который может и занимает на 20%-30% больше времени, но позволяет создать в несколько раз более производительное приложение. И при кодинге я всегда делаю замеры на скорость, ведь даже на простых запроcах к БД можно можно на порядок или на два ускорить выполнение — просто изменив кострукцию запроса, учитывая особенности работы СУБД. Аномальные задержки достаточно просто увидеть и переделать при написании нового функционала, а на последних этапах иногда нереально сложно, и всегда займет намного больше времени.

Согласно вот этому источнику, цитата на самом деле принадлежит Тони Хоару, Кнут просто ее популяризировал, и вот что имелось в виду:
However, Hoare was not saying, «concern about application performance during the early stages of an application's development is evil.» He specifically said premature optimization; and optimization meant something considerably different back in the days when he made that statement. Back then, «optimization» often consisted of activities such as counting cycles and instructions in assembly language code. This is not the type of coding you want to do during initial program design, when the code base is rather fluid.

И сразу все заиграло другими красками.
Есть термин 'preliminary pessimization', придуманный ЕМНИП Александреску. Под этим он подразумевает очевидные решения, которые будут «тормозить» — неэффектвиные алгоритмы, плохие выборки данные, пересылка огромного и ненужного кол-ва данных по сети и так далее. Ну и правильно — избегать и 'preliminary pessimization' и 'preliminary optimization' везде где это возможно. Например у меня есть в БД некие данные и мне надо посчитать аггрегаты по ним. Если, при прочих равных условия, мы будем считать агрегаты SQL-ем вместо загрузки записей в память — то таким образом мы избежим 'preliminary pessimization'. А вот если при этом не будем делать специальных индексов подял этого запроса(кроме очевиджных вариантов), не будем обвешивать запросы хинтами и до того как вскрытие покажет что тормозит конкретно этот запрос — мы не делаем 'preliminary optimization'
Не знаю, кто первый написал, что 1% кода может тормозить на 99%. Потом это утверждение повторялось с немного другими цифрами. Сейчас компиляторы сами оптимизируют так, что не получается сделать лучше. В 1980х была иная ситуация: переход с турбо-Паскаля версии 3 на ассемблер иногда давал резкое ускорение. Но и тогда не всякий такой переход выглядел правильным. Помню, как в курилке нашего ВЦ пили чай, и кто-то принес свежий номер журнала «Монитор». Там была статья с ассемблерным листингом, реализующим программирование мышки. Мышка была новым устройством, и мы все вставляли ее в свои программы для IBM PC XT. Кто на турбо-Паскале, а кто на турбо-С. Та статья вызвала хохот. Кто-то предположил, что авторы из пневмопушки мышкой стреляют раз им нужна такая сверх-производительность. (Мышки были на шарике — тогда это было достижением). Позже, через год, я работал в МВТУ (теперь МГТУ). Там я столкнулся с обучающей графической станцией. Она соединялась с ЕС ЭВМ и имела 30 ТВ Юность. Весь код для нее был на ассемблере — многие десятки тысяч строк! Все и тогда говорили, что на ЯП высокого уровня был бы лучше, и производительность бы не пострадала. Тогда было понятно, не понятно, что сегодня это не понятно!

Тоже "по молодости" ставил на performance-first, это казалось крутым. Но это требовало очень точного и зафиксированного описания задачи ("мамой клянусь, не поменяется до релиза ничего").
Вот только в реальной жизни это не так.
Единственное место, где реально такой подход применять, если хочется, — это всякие соревновательные контесты, типа отечественного highload cup или всякие примеры олимпиадного программирования.


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


Так что много лет уже следую принципу:


  1. Сначала сделать по т.з.;
  2. Потом сделать корректно (тесты, ручные тесты, выдача early bird, и любые другие способы проверить логику и реализацию с обратной связью. Тут может всплыть огромное количество нюансов, которые сразу и правятся);
    // Тут может произойти релиз, если нужно минимизировать time-to-market;
  3. Потом сделать быстро там, где есть проблема. А для этого нужны бенчмарки решения целиком, чтобы видеть бутылочные горлышки;
    // Вот тут уже релизим, если ещё нет.

Есть вариант, когда ты пишешь систему, в которой в Т.З. прописаны серьезные ограничения на производительность (не ниже ХХХ) — системы видеонаблюдения, торговля на бирже, какие-нибудь АРМ комплексы (real time и near real time). Тогда в любом случае приемка будет осуществляться в случае попадания в ожидания Заказчика проекта.
В случае обычных веб-приложений немного попроще — потому что тормозит, ну, да ладно — народ утрется. Хотя потери клиентской базы из-за того, то сайт долго открывался, тоже могут быть весьма существенны.
И это вовсе не отменяет пп1-2-3, просто возможность ускорения нужно закладывать на начальном этапе проектирования в случае, если это прям критикал… Либо делать несколько итераций продукта (с потенциальным полным переписыванием на каждой итерации)…

Если в ТЗ есть требования по производительности, то это 1-2 шаги (иначе задача как раз таки еще считается не сделанной корректно).
Например, код должен укладываться в 100мс на 99м перцентиле. Ок. И если он работает за 110мс — это не выполненное задание.
Но после первого релиза можно, при наличии времени, оптимизировать до 50мс, и тем самым немного поднять метрики продукта. (Пример из более-менее реальной жизни).

Закладывание возможности ускорения (как и будущие итерации) я воспринимаю как закладывание возможности дальнейшего развития и доработок. Если код уже написан так плохо, что его уже нельзя поддерживать уже на таких ранних этапах, то тут все плохо, как бы быстро/медленно решение не работало.
А возможность развития — это ведь вообще основополагающее требование к коду (если речь опять же не про «олимпиадное программирование»).

Насчет ускорения JS: разве он стал быстрее не потому, что больше ресурсов стало доступно JIT-компилятору (когда у вас одно ядро работает, а 2 других ядра профайлят выполнение и перекомпилируют код) — разве мы можем отправить эти имплементации на железо 20 летней давности, где C/C++ был незаменим?

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