Podlodka #374 – High Performance - podcast episode cover

Podlodka #374 – High Performance

May 27, 20242 hr 57 min
--:--
--:--
Listen in podcast apps:

Episode description

В выпуске поговорили как можно прийти к высокой производительности через Observability, Profiling и Benchmarking. Сергей Тепляков предложил простые критерии, как понять, что вам надо задуматься об оптимизации, а главное, развеял мифы, что всегда проще залить проблему покупкой мощностей. Новый сезон Podlodka Python Crew стартует 3 июня и посвящен инфраструктуре. Разберемся с мониторингом и трейсингом, найдем неочевидные способы оптимизации сервисов, научимся предотвращать фейлы с безопасностью и не только. Забирай скорее билет со скидкой в 500 рублей по промокоду INFRA_PYTHON: https://podlodka.io/pythoncrew Реклама. ИП Толстая Елена Петровна ИНН:507503278104, erid:2SDnjf3vUPK Также ждем вас, ваши лайки, репосты и комменты в мессенджерах и соцсетях!
 Telegram-чат: https://t.me/podlodka Telegram-канал: https://t.me/podlodkanews Страница в Facebook: www.facebook.com/podlodkacast/ Twitter-аккаунт: https://twitter.com/PodlodkaPodcast Ведущие в выпуске: Стас Цыганов, Евгений Кателла Полезные ссылки: Выступления Martin Thompson, которые обсуждали в выпуске https://www.youtube.com/watch?v=VbTJHQe3nNg https://www.youtube.com/watch?v=03GsLxVdVzU Обсуждение .Net коллекции span https://www.youtube.com/watch?v=5KdICNWOfEQ

Transcript

Всем привет-привет. Это подкаст Подлодка. И сегодня мы пишем выпуск про перформанс или оптимизацию. Что-то вот про это. Разберемся по ходу выпуска. Вы уже знаете название, на чем мы определились. Мы еще нет. Посмотрим и разберемся. Помогать мне сегодня вести выпуск будет Женя. Привет, Жень. Всем привет. А в гости мы позвали как-то все в мире циклично, и поэтому у нас пришел...

К нам в гости. Гость из выпуска 25. Небезызвестного выпуска «Вам в шашечки или ехать». Спасибо названию за то, что, возможно, его послушали меньше раз, чем должны были. И в гости к нам пришел Сергей Тепляков. Всем привет. Привет-привет. Расскажи немного про себя. В прошлый раз мы уже, кажется, обсуждали оптимизацию. Если честно, выпуск был настолько давно, я уже не помню, о чем мы там разговаривали. Расскажи, что у тебя изменилось за эти годы, кем работаешь, чем занимаешься, что тебя интересует.

раз всем привет. Ребят, спасибо, что позвали еще раз. Я все еще работаю в компании Microsoft. Сейчас я principal developer в подразделение, которое называется Azure Physical Networking, и я там всего полгода. Это команда, часть, которая Core Azure пилит. Core Azure — это Compute, Storage и Networking. То есть вот я в части...

одной из них. Вот до этого я 8 лет занимался билдами в подразделении, которое называется OneAS. То есть это группа, которая делает... Она когда-то делала MSBuild, сейчас не делает MSBuild. Это... внутренние билдтулы, внешние билдтулы. Если кто-то слышал про Bazel от Google, вот, то есть наша команда делала аналог. Это штуки, которые для билда офиса, винды. И потом я занимался этим делом, потом перешел в distributed cache там же.

То есть это такой весьма high-loaded. И вообще это довольно интересная тема. У вас, насколько я помню, был выпуск про билды. И это такая, на первый взгляд, казалось бы, простая тема. На самом деле там много всего зарыто. много всего интересного. Я когда-то блогал много на русском, сейчас я сколько-то блогаю на английском, в основном про C-Sharp, когда-то писал много про дизайн, паттерн и даже книжку своял уже после переезда в Штаты. Это была тема

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

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

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

которая появилась за последние полгода дополнительного, которой было бы очень-очень интересно поделиться. Шикарно, шикарно. Как-то так. Перед тем, как начнем, фан-факт. Когда мы работали с Егором еще в Rambler, и, собственно, Егор был локальным лидом всех айосников у нас.

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

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

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

про которую мы сегодня будем говорить. Действительно, есть много вещей с этим связанные. И сейчас часто слышим про high load, всякое такое. И в данном случае это не совсем то же самое, с моей точки зрения. То, о чем мы будем говорить сегодня, это... У нас есть коробочка, и коробочке на вход что-то подается, что-то посчитать, переживать, веб-сервис, просто коробочный продукт. У вас есть Visual Studio, у вас есть там Rider, что-нибудь такое. И потом кто-нибудь говорит, смотрите, ребят.

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

То есть первый аспект это throughput, то есть пропускная способность. Или bandwidth, это максимальная пропускная способность. Мы там знаем, что у нас есть 10-гигабитная карточка сетевая, это означает, что мы можем протащить 10 гигабит данных в секунду. Теперь это отдельный аспект, то есть сколько наша система может переживать данных от входа на выход за единицу времени. То есть у нас время фиксировано, вот этот вот load, сколько времени у нас потратится, либо сколько у нас RPS может быть.

Другой аспект — это, например, latency. Они иногда могут противоречить друг другу, зачастую. То есть, когда у нас подается сигнал на вход, сколько нужно времени, чтобы этот сигнал дошел до выхода. И любой датнетчик или джелист знает, что, например, там... В частности, в .NET есть GC, например, сборщик мусора. И у них есть два разных режима. Workstation и сервер. Вот один оптимизирован для latency, а другой оптимизирован для throughput. В зависимости от того, что ваше приложение делает...

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

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

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

То есть у нас есть ресурсы, у нас есть задачи, насколько мы хорошо можем это делать. Еще один аспект у перформанса, это у него есть там правильное название, что-нибудь типа QN Theory или что-то такое, но я это называю скорее... То есть вот у нас есть система, которая подается на вход количество запросов. Ну, как простой пример. И когда у нас запросов, например, 1000 в секунду, у нас используется 10% ресурсов.

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

То есть некоторые системы более эластичные, некоторые системы менее эластичные к нагрузке. Что происходит, когда мы достигаем определенных пределов? Мы обычно используем либо троттлинг, либо еще что-то, либо мы начинаем накапливать, накапливать, накапливать, и пропускная способность падает. Есть вот эти три аспекта, о которых, наверное, мы будем говорить сегодня. И как сделать в рамках одного продукта, одной системы, поднять одну из этих метрик, чтобы она была лучше. Понятненько.

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

Четко понятно, что что-то идет не так. Первый кейс — это когда пользователь видит, что, не знаю, нажали кнопку крестика, и приложение долго закрывается, бесит, и ты вместо WhatsApp начинаешь пользоваться Telegram. True Story у меня ровно так и случилось. Или другой пример, который ты привел, это когда у нас эластичность плохая, нагрузка растет, растет, растет, и в какой-то момент случился клифф. В системе капец. В общем, это все можно считать какими-то, ну, если не инцидентами, то...

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

При этом на простецкие, не знаю, 1000 RPS каких-нибудь условных, он, не знаю, жрет в большом облаке несколько нод и CPU под 90% у него постоянно. Вот про такие кейсы мы будем говорить, когда в целом... Как бы оно работает, но мы знаем, что код, ну, грубо говоря, не оптимальный. Будем говорить. Мы, наверное, один из следующих моментов, наверное, самый-самый фундаментальный, да? А надо ли?

У нас время ограничено, и у нас много задач. А почему перформанс? Почему нам это должно быть важно? Мне как инженеру это прикольно, это интересно, здорово, но... Это очевидно, что это неправильный подход, особенно для senior principal engineer. Ну, это очень плохая философия, когда ты приходишь, я занимаюсь только тем, чем мне нравится. Идеально, когда ты занимаешься тем, что тебе нравится, и еще это приносит пользу бизнесу, да?

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

быть фича сет это может быть количество back density это может быть performance И тогда мы, ну, есть, может быть, слышали, есть такой эффект второй системы, когда мы начинаем дизайнить вторую систему и делаем Simabuter, который вообще получается абсолютно ужасным, да. Но есть успешные кейсы, ну, вот пример, который мне ближе к телу, да, например, это... переписывание компилятора C Sharp, он был изначально написан на C++, и он переписывается на C Sharp.

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

И не особенно паримся за performance, если мы говорим об applications. То есть есть много-много специфических вещей. Если это reusable library, если это системный код, ось, базы данных. Там перформанс идет с самого начала, и это must-have, это фича. То есть есть виды систем, в которых перформанс — это фича.

В Enterprise-приложении обычно перформанс не является фичей до определенных моментов, когда это начинает мешать бизнесу. Либо влияет на velocity, да, то есть, например, Microsoft, вот эта билд-система NextGen, о которой я говорил, это...

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

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

Кажется, у нас проблема в плане перформанса. Например, какая? Вот там есть исследование того же Амазона, что что-то типа увеличение респонс тайма на 100 миллисекунд сужает воронку продаж на... Какие-то там дикие величины. Понятно, что я это сейчас говорю по памяти, но это вроде как, насколько я помню, такой весьма... Или это у Гула была, или у Амазона.

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

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

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

У меня примеры на моем текущем проекте. Я когда пришел, там сразу мой менеджер, новый старый менеджер, сказал, слушай, как у тебя опыт с профайлингами? Я такой, что, давай, говори, что? Вот у нас там есть система, которая там падается out of memory. Это мы запускаем на большом железе с 400 гигами памяти. Воу, окей, хорошо, можно отожрать 400 гигов. Плавали знаем, действительно можно. Давай сюда. Вот, и я этим занимался. Но другие моменты, когда вроде бы как явных проблем с перформансом нет.

Но в сложной распределенной системе, которая... Ну, то есть большинство core-сервисов, там, клауд-провайдера, а не high performance. Когда идет у бизнеса scale, и, например, когда у вас счет от клауд-провайдера придет такой, который перекроет всплеск revenue, Ну, наверное, это можно допустить один раз, а потом сказать, ну, ребятки, ну, надо что-то делать.

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

Хорошо. Потому что вопрос хайлоада и горизонтальное масштабирование, у этого есть просто дико интересный момент. Наверняка многие слышали про закон Амдала. Вообще у этого закона есть очень интересная история вокруг него. что этот человек, Мдал, видимо, очевидно, капитан очевидность, он занимался толканием мейнфреймов, и когда пошли персональные компьютеры и распределенные вычисления больше в ходу, он такой...

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

распараллелить. Классно. Если в этом батче 10 тысяч элементов, предположим, и обработка каждого из них абсолютно независимая, то мы можем действительно увеличить скорость в тысячу раз. В идеале. Но если у нас в батче... Один запрос и оверхед первого этапа 90%. Что мы будем распараллеливать? У нас просто нечего распараллеливать. У нас этап, который параллелится, он занимает 10%. Соответственно, максимальная выгода будет 10%. Но у этой теории, это у закона Мдала дает...

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

100 машин, 100 бэкэндов и так далее. В реальности же, на самом деле, у вас за этим бэкэндом, который что-то считает, лежит база. Точка синхронизации. И в результате, когда мы подняли этот параллелизм, например, до 3, 4, 5 или скольки-то, мы получаем линейный... kind of прирост производительности, а потом накладные расходы на синхронизацию в какой-то точке синхронизации. Зачастую у нас работа делится на расправелили, потом объединили.

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

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

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

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

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

Вот. Я еще хотел привести один вот прям конкретный пример с параллелизмом. Это именно параллелизм, это не горизонтальное масштабирование на разные ноды, но вот прям очень хороший пример. Вот эта система, которая жрала там 400 гиг памяти. У этого есть там свои, то есть система старая, она как раз V1, и у нас есть работа по системе V2. И мне нужно было купить время, по сути, своими оптимизациями.

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

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

Такой, смотри, такой, уф. И это там дикий оверхед. Такой, окей, хорошо, это плохо, убрал. Бенчмарк. Мы, на самом деле, придем к тому, как это проверять. Наверное, я тогда не буду об этом сейчас говорить. Но это был пример того, что... параллелизм хорош тогда, когда он, то, что называется там embarrassingly parallel problems, когда они...

заточены под это. Они проблемы, которые легко разбиваются на куски. Куски автономные, процесс объединения результатов минимальный, и эти куски большие. А, например, очистить хэш-сет... особенно если там 10 элементов. Ну, нет смысла вообще пытаться что-то. Или у нас есть там 10 хешсетов, мы хотим их очистить параллельно. Если эти хешсеты почти пустые, это будет очень быстро сделать последовательно, чем тратить накладные расходы на процесс создания разбиения.

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

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

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

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

И в результате мы тратили просто кучу времени на абсолютно непонятно что, потому что это было не нужно. Выполнение ненужной работы в целом, это как бы прям вот один из тем, которые было бы интересно затронуть, как способ оптимизации, как найти... что мы делаем что-то, что не нужно делать. Это может быть какое-нибудь копирование памяти или там сборка мусора, да? Опять, я работаю с dotnet, но то же самое будет там в Java, в Go. Сколько времени мы тратим на сборку мусора?

Бывают кейсы, у нас были кейсы, когда время, то, что называется метрика timing GC, она была 70%. 80%. То есть... В результате приложения оно большую часть времени собирает память. У нас был просто вообще потрясный инцидент с моей предыдущей командой, когда мы там мигрировали с полного фреймворка на .NET Core, и вот этот вот, я уже упоминал про ServerGC и WorkstationGC, который вот ServerGC, это прям вот для бэкэнда, ух!

Вот. И конфиги, они по-другому выглядят. И мы забыли. И мы использовали Workstation GC, который вот там однопоточный и все. Там есть еще ряд моментов, почему он более медленный. И помимо того, что мы отжирали памяти там 500 или 700 гиг, Это была машинка с 1 терабайтом памяти. И оно просто все стало. Просто мы ничего не делали. Там 99% мы были Time NGC. То есть перформанс проблемы могут быть самые-самые разные. И это может быть...

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

а не один компонент в одном файле. Даже один компонент может работать с несколькими потоками. В результате какая может быть проблема? У нас есть система, которая работает в много-много потоков. Все они шуруют в логер. Логер... Соответственно, файл один. Мы не можем писать файл с нескольких потоков. Точка синхронизации. В результате все у нас что делают? Ждут. Они ничего не делают полезного, они ждут на файле.

Это еще один юскейс. Есть паттерны, как это можно метигейтить. Это антипаттерн, как там обратная версия... Я просто помню, какой-то был еще тоже пример про то ли про спутники, то ли еще про что-то, то, что там такая же история, то, что более важные операции с более высоким приоритетом. Можно так построить систему.

Один из примеров, как с логером, что операции с более высоким приоритетом, они, соответственно, ожидают операции с более низким приоритетом. И здесь вот логер, очевидно, то, что он полезные нагрузки не выполняет. Да-да-да, это да. Я просто название забыл. Я тоже не помню название этого дела. Вот, ну то есть у нас lock-contention — это еще один паттерн. Там GC — другое. Неправильная сложность алгоритмов — это, ну, наверное, самая такая вот типовая проблема.

когда как обычно да то есть у нас где-то нет кэша мы что-то вычисляем что-то вычисляем Это дорого. При этом это могут быть каскадные эффекты в распределенной системе, когда мы все время обращаемся к кому-то и портим жизнь кому-то. То есть параллелизм и оверхед от параллелизма это... A problem, но это далеко не самая обычно большая перформанс-проблема. Мы можем поговорить об этом, то есть мы там, если хочется, когда мы говорим о системе, то...

очень разумно разделять два вида работ. И в контексте параллелизма это тоже очень важно. Условное, грубое, но оно понятное и простое разделение, это операции могут быть CPU-bound или IO-bound. Что это такое? CPU-bound это мы считаем. Это что-то, что работа выполняется нашим процентом. IO-bound — это что-то, что работает тот-другой. Диск — это мы сказали быстро, а кто-то другой делает относительно долго.

Или другой сервис. Мы ему говорим, слушай, вот тебе. Он такой, понял. Чтобы сказать ему, тебе требуется CPU ресурсы, упаковать пакетик, что-нибудь такое. Это маленькая работа. Но обычно имеется в виду, что в IO-bound сценарии... Время, которое требуется на инициацию запроса, гораздо меньше, чем времени требуется, которое на выполнение. И там параллелизм совершенно разный. Потому что если у тебя есть 8 ядер,

то у тебя может быть максимум 8 щитоводов, потому что дальше у тебя уже надо будет, погоди, я переключился, посчитал другим, и идет переключение контекста и waste of time. На iobound ты, в принципе, если у тебя какая-нибудь коробочка, которая только редиректит. что-то, но она может логически одновременно выполняемых запросов выполнять тысячи и тысячи, потому что мы на самом деле ничего не делаем в этот момент, мы просто отправили и ждем. И даже вот в этом плане, как элемент...

или вот сколько система может обработать в единицу времени, вот этот вот аспект и понимание того, какая природа твоих операций и как эта природа операций будет влиять на skill ability твоей системы. Это важно. Поэтому здесь в потоке это маленький нюанс, если мы занимаемся вот в этой области CPU-bound операции. Можно я накину один пример, он немножко про другое, но мне кажется, он очень прикольный как раз в контексте масштабирования и IO-bound операции.

просто из опыта. Один раз довелось дебажить систему. Короче, проблема была в том, что начиная после каких-то спайков в нагрузке... все начинало падать. Просто там не масштабируется. Хотя должно масштабируется, но ничего не масштабируется. И все это там крутилось. Очень простенький сервис. У него задача не очень большая. Принять запрос и раскидать его дальше на какое-то количество машин. То есть один запрос...

в несколько исходящих. И проблема в том, что это все был сервис на ноде, запакованный в Docker Image, который нам дали, грубо говоря. То есть к нему у нас, по сути, доступа к исходнику никакого нет. Надо просто разбираться с конфигурацией собственно самого сервиса и его масштабирования. Потому что он просто в какой-то момент ложится без абсолютно понятных каких-то паттернов. Короче, Long Story Shot выяснилось, что проблема была в том, что...

количество исходящих запросов у нас выросло, потому что это как раз управлялось конфигурацией. И в итоге из-за параметров масштабирования, из-за того, что мы говорили, да, конечно, каждая нода может принять 10, 20, 50 входящих запросов, на пофигу, это превращается... Каждый запрос превращается в 10 исходящих. В итоге на каком-то масштабе у нас каждая машина просто начинала задыхаться от количества исходящих. Пулы просто переполнены. Оно все ждет, когда эти все коннекшены освободятся.

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

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

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

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

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

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

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

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

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

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

или использование клауд-провайдера экономически неэффективным. Дэвид Ханцелман, DHH, в общем, автор Ruby on Rails. Такая интересная, неоднозначная фигура. У него была куча постов по поводу переезда. с клауда на on-prem. Было дико успешно, было здорово. Опять, у тебя майнсет, что...

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

Это работало до определенного момента, и потом нужно нам подумать и перейти с вот этих вот экстенсивных рельсов, когда мы вкидываем просто деньги, и оно не работает, сделать степбэк, и такой, стоять не пойдет, надо переписывать. Соответственно... Закругляю. Деньги. Отличный инструмент. Очень-очень классно, когда у вас есть другие инструменты в распоряжении. И вот об этих инструментах мы и собираемся говорить.

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

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

Наверное, есть только интуитивные ответы, наверное, есть какой-то правильный книжный ответ. Я не знаю, существуют такие вещи, как правильные книжные ответы или нет. Но, наверное, вот high performance — это вопрос эффективности. Это когда у нас в рамках вот этих... вычислительных мощностей, что бы это ни было, вид Hardware какой-то, вид дисковой подсистемы и так далее, что мы можем сделать? Сколько мы можем сигналов со входа переживать в правильные сигналы на выход? Это High Performance.

Highload — это, скорее, наверное, вопросы, насколько наша система эластична и будет выдерживать... спайки в нагрузке, которые могут быть там на несколько порядков. То есть очевидно, что ни одна on-prem-система не может быть...

Скажем так, мне сложно себе представить on-prem систему, которая будет cost-effective, когда у тебя нагрузка может плавать на несколько порядков. Потому что тогда тебе все равно нужно ориентироваться на пик, и никакие оптимизации тебе... не помогут избавиться от сверхдорогого железа. И вот в этом плане, как мне кажется, вот этот high load и возможность горизонтального масштабирования, которое тебе будет позволять справляться с вот таким вот всплесками, вот это вот больше в моем понимании туда.

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

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

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

Да, и куча, вот любые бокс-продукты, это прежде всего high performance. Когда это имеет смысл, да, ну, то есть у тебя любые system level или сложные вещи, я же говорю, там, современные редакторы, игры, там будет high performance, но по сути... сути, там high load будет в аспекте какой-нибудь онлайн-миров, да, но это будет вот другой аспект, да, то есть это уже скорее вот, но тебе нужно решить high performance все равно, потому что если у тебя игрушка тормозит, то, наверное...

Чуть не то. Ты сам аккуратненько подвел нас к следующему вопросу. Давай как раз обсудим, в каких там продуктах, видах продуктов это особенно важно. Ну да, то есть вот то, с чем я работал, и опять можно экстраполировать.

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

и при этом высокая производительность, и при этом безопасность. То есть любые формы баз данных, да, это просто... Если кто следит за автором RavenDB, у него есть куча постов, там просто невероятное количество каких-то трюков в плане перформанса. используется. Тот Net Runtime, да, или там Java Runtime, Java GC. То есть это будет просто дичайшее количество оптимизаций. Там какой-нибудь Elasticsearch. Все это там невероятное требование к перфомансу. Любые базовые библиотеки...

Там это как бы абсолютно другой мир, в котором надо подходить с точки зрения дизайна по-другому, с точки зрения перформанс. Любые коробки абсолютно однозначны. Backend, it depends. То есть, опять же, у тебя может быть backend, который сейчас один. И если сейчас есть один сервис, который выполняет работу, то когда ты упираешься в performance bottleneck по стартапу, elasticity, чему-то, что нам плохо, мы понимаем, что нам плохо, такие варианты есть.

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

Никто не отменял. Спайки. Если мы просто выбрасываем деньги ни на что, это вообще не очень здорово. У меня приятель работает в OpenTelemetry в Microsoft. Это все дикий high-load. Это опять. Окей.

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

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

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

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

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

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

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

Но есть огромное количество Perf Sensitive систем, которые написаны на управляемых языках, у которого есть куча преимуществ и так далее. Есть куча недостатков, есть куча преимуществ. Но даже здесь контекст имеет значение и... Опыт группы, например, может иметь просто колоссальное значение при выборе технологий для получения high performance. Просто потому что они смогут быстрее понять какие-то вещи, которые можно делать или не делать.

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

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

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

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

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

как работаешь ты, что у тебя в жизни происходит, и использовать это как фидбэк-клуб. Почему это важно? Потому что, например, ты приходишь на работу, билд занимает 2 часа. Это плохо или хорошо? Хрен его знает.

It depends, да? И ты такой, ну, значит, оно же так надо. Значит, кто-то же решил, значит, это же что-то вот правильно, вот так вот это надо. Такой, подожди, подожди, подожди. Ну, у нас тут вот такой вот проект, это не имеет никакого смысла, чтобы оно занимало столько времени. И ты такой, не-не-не-не. идем и чиним билд, потому что это проблемы. О, блин, это у нас тесты запускаются там в течение часов. Это перформанс-проблема, которую стоит чинить или нет? С моей точки зрения.

Это перформанс-проблема, которая влияет на культуру и майндсет того, что мы хотим eliminate waste. И в очень большом, вот прям вот в таком методологическом плане, что ну блин, это явно мы ерундой занимаемся. Или у нас, например, DRI приходит, это в Microsoft, он называется DRI, это дежурный designated responsible individual, это on-call, инженер. И такой, о, у нас тайм-ауты.

Тикет с тайм-аутом, и человек выясняет два часа, что у нас тайм-аут. А у нас вот тут вот latency, оно плавает, у нас тайм-аут. Это достаточная проблема, чтобы заниматься перформансом или нет? Один раз, я могу сказать, не знаю. Вот, у нас ровно такой случай был в одной из систем, spike timeout. Такие, окей, окей, клево, давайте посмотрим. И все начинают там рассуждать, думать, это проблема, там диски, шмиски, что-то такое. И это...

огромные трудозатраты уходят на выяснение того, а почему у нас тайм-аут происходит. Потом такой, о, а дело все в перформансе, потому что у нас перформанс плавает, и там запрос может выполняться очень долгое время. Или там, например, вот в одной из систем, которую я вначале оптимизировал, за счет того, что startup time был в часах, два часа, то во время деплоя у нас там load balancer уже потом такой, а ладно, все, пускаем трафик на всех, я устал, я не могу.

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

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

То есть у нас есть очевидные косты, у нас есть очевидные инциденты, у нас есть... Я периодически смотрю, что происходит с системами, с какими-то метриками. Time in GC, startup time, какие-нибудь exception. Что-то, что такое, такое, ой, блин, а вы знали, что? Вот, и... Там еще один пример в другой команде. Мы запускаем, анбордим нового кастомера. Новый кастомер — это новый workflow, связанный с апдейтом нетворкинга. И у нас система ложится. У нас high load.

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

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

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

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

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

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

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

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

той workflow-системе, в которой я занимался. То есть у нас был там серьезный инцидент, когда два дня система не работала. Это опять маленький-маленький кусок, поэтому это не то, что там ажура сломалась, но тем не менее. И проблема еще в том, что... Ты смотришь на метрики. У нас там миллионы запросов к бэкэнду. Такой, подожди. А что мы делаем такого? Почему у нас есть миллионы запросов к бэкэнду? Мочится ли эта метрика на мое понимание...

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

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

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

Мы пытаемся пойти это всё и в каком-то виде починить. Естественный вопрос, который возникает в голове, а не стоило ли об этом всём подумать пораньше, когда мы, собственно, фундамент строили нашего здания, только нашу систему проектировали, не стоило ли думать в этот момент? Собственно, как будто бы вторая альтернатива — это то, что мы можем слишком рано это сделать и наоптимизировать, как ты приводил пример. Взяли и сели все писать на C. Но здесь есть еще аспект того, что...

во всем у нас, мы, возможно, не очень хорошо в нем разбираемся по сравнению с нашим родным, например, языком, но, опять же, где-то там маячит проблема преждевременной оптимизации. Вот что про все это думаешь, когда самый правильный момент для того, чтобы... оптимизации задуматься. Окей, то есть очевидный ответ это it depends, да? Спасибо. It depends. Но теперь к более конструктивному ответу, да?

Есть вещи, которые, вот я говорил про там розлины, переписывание, создание второй системы, когда у тебя уже понятны Perf Requirements, да? Они не всегда понятны с самого начала. И иногда они понятны, то есть есть домены, в которых Perf Requirements понятны. достаточно, да, то есть мы пишем какой-нибудь там опять ID, редактор, очевидно, что у тебя будет, ты можешь понимать, о каком количестве задач лодим идет речь. И очевидно, что если ты не готов к этому, то...

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

То есть вот, например, билд-система, там сразу было очевидно, что тебе нужны определенные дизайн-решения, которые нужно закладывать с самого начала. Пример. Когда ее создавали, было очевидно, что эта билд-система должна скейлиться на уровне билда Винды и Офиса. Чтобы вы понимали, там просто одних файликов будет 20, 30, 50 миллионов. Очевидно, что ты даже пфуть в виде строки, а там может быть даже больше. То есть это уже будет большой накладный расход.

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

Предметные области, которых нужно об этом подумать заранее, потому что потом это впихнуть будет невозможно. Опять же, тот же MSBuild, другая билд-система. Ты потом не впихнешь это обратно. Это не получится. И в этом плане у тебя будет просто какие-нибудь skill ability limits для этой системы, которую будет очень сложно победить. Нужно будет что-то познавать и делать заново. Для Enterprise приложений у тебя наверняка ценнее твоя продуктивность, выход на рынок, фича сет.

И потом наверняка можно будет подойти к, наверное, следующий этап. Поговорим о том, что мы пройдемся с профайлером, посмотрим боттлнеки. И, наверное, на неоптимизированной системе, если ты берешь специалиста по перформансу. 5, 6, 10x Perf Boost, наверное, можно получить. Опять, 10x, наверное, сложнее, 5, 6x, может быть, просто срезая low-hang food. И возможно, что этого будет достаточно на очень-очень большое время.

А иногда можно и больше поднять струб. И в этом плане для классического enterprise систем будет правильнее идти, примерно понимая, о каком лоде идет речь. Чтобы понимать, твое пространство решения, оно в принципе подходит к этому или нет? Или это очевидно работать не будет? Потому что, ну, какой-нибудь пример, у нас есть автодополнение в ID, и мы на каждый чик будем обращаться к базе данных.

хорошо, latency для печатания, чтобы было нормально печатать, тебе нужно сколько-то там, типа 50 миллисекунд или сколько-то, latency для обращения к базе данных будет вот такое, именно поэтому там у JetBrains были долгие дебаты, переводить его в Out of Proc. или нет, потому что это важный, сложный баланс между этими. То есть в результате тебе нужно прикидывать, о каких ограничениях с точки зрения лода идет речь, хоть чуть-чуть иметь это в виду. И если ты такой, да я...

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

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

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

по throughput, по memory footprint. И в идеале нам нужны... запихнуто что-то в... Большая часть систем метрик ты можешь поставить... То есть не только Average, смотри, да, не только средненькие, не только Min, да, а все-таки еще там P95, и чтобы посмотреть хоть какие-то Outlier'ы у нас есть, и вот нам нужно зафиксировать, что у нас есть сейчас. Для этого нужна система, чтобы у тебя Top Level...

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

После этого мы переходим к тому, что, окей, системы сложные обычно. Нам бы понять, вообще, проблема-то где? Вот, то есть, если у нас RPS-ов мало, да, или у нас эластичный... С чего-то надо начать. Предположим, что у нас мы задыхаемся, и там RPS-ов мало, у нас входной трафик 100k в секунду может быть, а мы можем переживать 50, и потом дальше система падает. Классно. То есть дальше нам нужно...

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

Вот, поэтому нам нужны какие-то инсайты о том, какой кусок кода работает неправильно. Обычно это можно разбить на несколько этапов, чтобы мы поняли вообще, это хотя бы вот этот компонент, эта подсистема, и потом дальше мы переходим к инструментам. Метрики — это один из техник и инструментов. Нам нужна observability, чтобы это увидеть. Второй этап — это в идеале. В OpenTelemetry даже есть proposal на профайлинг.

чтобы мы получали какие-то трейсы временные, и мы могли сказать, что вот этот вот кусок в этой распределенной системе занимает столько времени с какой-то там статистическим распределением. Там у Microsoft, я уверен, что у других, есть там Microsoft, называется Azure Profiler, который ты можешь настроить, и он будет снимать сэмплы, и ты можешь понять, о, вот этот вот кусок кода, мы выпадаем здесь, вот куча хитов.

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

Оно является в некотором случае автоматом. Если ты там string literal где-то в коде у тебя есть, он на самом деле не аллоцируется каждый раз, он откуда-то где-то реализируется. Но ты можешь сказать string.intern. И тогда, если у тебя, например, есть... но в данном случае там конфигурация сетки, и у нее много одинаковых имен там есть, одинаковых вещей. Айпишник, что-нибудь такое. И ты говоришь, что, о, а давайте мы при диссерилизации пройдем через интернирование.

И таким образом мы будем стринг Дедуб делать. У нас проблема с памятью. Это важно. Логично. Хорошо. Первое, например, почему эти метрики дико важны. Если у тебя есть атомарное изменение, которое ты делаешь, и ты видишь дроп в памяти изменения, ты можешь сказать, это было полезное изменение или нет. Но второе, в данном случае, когда я посмотрел в этот профайлер ажуровский,

Мы сидим в string and turn на лог-контеншене. То есть 90% времени работы этого бэкэнда занимался лог-контеншен. Такой, блин, жулики. Ужас какой. Вот такой, окей. Это сразу же показало одну из важных проблем. Соответственно, когда мы идентифицировали проблему, мы идентифицировали ее наличие. Теперь нам нужно перейти к...

Такой scientific method. Выдумать предположение, где эта проблема есть. Для этого нам нужны инструменты, которые покажут, где эта проблема есть. Это может быть профайлер, который автоматом запускается в бэкэнде. Есть профайлеры третисторонние, которые можно запустить на тестовом оборудовании. Могут быть какие-то формы симуляции, которые можно запустить с маскированными данными. У этого есть куча проблем обычная.

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

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

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

кричать обычно. То есть у тебя есть long hanging fruit, где система проводит подавляющую часть времени. Это даже не пара, это принцип 80-20. Они распределены дико нелинейно. Вот, мы это починили и смотрим end-to-end impact. И в этом плане луп именно такой. Есть end-to-end метрика. Мы используем профайлер, чтобы понять, где проблема. Мы делаем решение. После этого я обычно перехожу к бенчмаркингу, чтобы...

Ну вот, например, у нас есть какая-то такая структура данных, такой алгоритмик. Ну что-то мы хотим поменять. В плане string and turning я взял и добавил кастомный string and turning. Две строки кода. Очень интересное было, там я потом мой постик написал об этом. Прям интересное такое discovery, что вот встроенный string and turning, он действительно в 100 раз медленнее. Вот так вот. И потом такой, о, а как померить...

В изоляции новый стриминг-термин. Бенчмарк, о, он действительно в 100 раз медленнее. Это не значит, что мы в 100 раз быстрее будем стартовать, правильно? Но, тем не менее, у нас есть уже какое-то понимание, что это решение объективно лучше. Потом мы запускаем end-to-end систему, деплоем тест или еще что-то, видим дроп.

То есть в данном случае мне было довольно легко это делать, потому что я локально мог запускать на субсете production данных. Ну, они не настоящие production данные были, но подмножество данных, которые довольно представительные были. Я запускаю локально, вижу, что у меня там стартап тайм дропается с 2 минут до минуты 20. Отлично, идем. Создаю пиар, в котором есть данные о бенчмарке, данные о локальном тесте.

Они потом деплоятся, мы смотрим реальный production impact. В результате flow работы над production fix именно идет, имея в виду топ-левел максимально end-to-end-ish импакт на систему. Не всегда легко, не всегда можно. Перейдем пример к этому. Так, мы как будто бы одновременно прошли и по, собственно...

циклу и по тому, по входящему в этот цикл инструмент. Да, на самом деле, да. Они просто связаны, но здесь просто, что вот надо важно понимать, как внутри этого цикла, какие мы инструменты используем и почему они важны. И в этом плане... Самое плохое, что может быть, это когда у тебя есть performance improvement без этих данных. Мы наколопатили, усложнили, упростили. Не знаю, мы сделали работу. И ты такой, а чё? Такой, не, ну это ж лучше.

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

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

throughput, latency, time and GC были такие, после этого всякие. Я понял, почему ты тратил 3 дня своего времени. Если этого нет, такой... И вот этот вот майндсет, что перформанс важен, но перформанс должен быть очень data-driven, он погасит все вот эти вот... Стас, ты говорил о том, что ну вот смотри, перформанс всем важен, поэтому все будем... Такой...

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

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

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

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

И вот у тебя поехали метрики. Вот у тебя тайм-ауты этого сервиса. Вот у тебя стартап тайм. Вот у тебя деплоймент велосити. Вот у тебя... Мы теперь не могли все фича-флаги включить, потому что мы out of memory были. Теперь мы дропнулись на вот столько. И там 120 гиг медиана упала. Такой, вау, все. Теперь понятно, что мы делали. Понятно, почему мы тратили время. Понятно, вот это уже легко трансферится в что-то, что ты можешь понять.

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

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

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

Андрей Киншин, который работает в JetBrains, автор продан .NET Benchmarking, он автор Benchmark.NET, что используется всем .NET комьюнити. Охренительный тул, очень здорово. Очень круто. У него есть несколько особенностей. Этот тул делает все возможное, чтобы результаты были стабильными. Ну, то есть, это очевидно, что у тебя вот эти вот бенчмарки, они должны запускаться на одном и том же железе. Желательно, чтобы у тебя не было никаких noisy neighbor.

То есть этот backend он делает только вот это вот. Вот вся идея вот этих вот performance, regression и все остальное, то есть делаем в TB. У нас есть метрики, мы уже определили, что топ-левел метрики это must-have. Самый простой способ — это на них иногда поглядывать. И такой оп, такой о-о-о, плохо. Более хороший способ — это попробовать настроить алертинг-рулы в продакшен, что... Там, когда в продакшн приехала, и все плохо. То есть у нас такая себе пирамида перформанс.

такого вот detecting, вот чего-то такого, да? То есть, вот первое, мы глазками. Ну, нет, первое, это нам позвонил кастомер и сказал, а у нас ничего не работает, да? Очевидно, что это вообще плохо. Вот, там... Второй этап, это наш DRI, там респонс был этот, смотрит такой, о, блин, брат, все пропало, что делаем? Там третий уровень, у нас алертинг на протсистеме, потому что там трафик именно такой, как надо, мы понимаем, что изменения там, это плохо-плохо-плохо.

Это следующий этап. И даже вот этот уже этап, он уже не очень простой. Потому что у тебя перформанс-метрики могут фонить, и это не то, что легко сделать алертинг, но doable. Дальше идет все сложнее и сложнее, потому что... В тест-среде. Релевантно ли она показывает статус продакшена? Такой же трафик, такая же динамика, такое же оборудование, такая же эластичность.

уже немножко сложнее. Можно попробовать. Можно попробовать сделать Perf Suite на end-to-end, когда мы запускаем что-то, что симулирует трафик и примерно смотрит, нет ли у нас там 2x изменений. То есть на 10% Я уверяю, что очень мало кто, кроме сверхбольших компаний, detected regression в 10%. Там хотя бы совсем плохо. Потом дальше, если мы идем о системах... Прямо, вот, что является фундаментом. Тот же .NET. Runtime.

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

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

Это боль, боль для организма, физическая и ментальная. Это важный сигнал, важный фидбэк. Вот, мы такие, так, окей, мы сломали перф. Плохо, хорошо, починили. Сломали перф опять. Твою мать. Что-то не то. То есть можно легко выявить, а нужно нам это или нет, исходя из того, насколько больно нам от перфоманс-регрессии. Я бы сказал так. Для .NET Core, для платформ, это настолько больно, что это неприемлемо не иметь.

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

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

производительный код? Ну, это в целом мы, наверное, чуть-чуть об этом касались, и я бы сказал, что здесь есть две вещи. Я начинал с C++, и в... Это был какой? 2003-2004? И там была очень интересная серия, на самом деле это одна книга была, Гербасатора, это довольно известный дядька в мире C++, и он, у него была книжка, что-то типа там C++ Coding Guidelines. И вот... C++ сложный, у него одно и то же можно сделать 18 способами. И за 21 день. Обязательно.

машина времени, и потом легко решать. И он приводил пример, что у нас есть преждевременная оптимизация, когда мы явно выжимаем перформанс и делаем что-то вот так вот. Но с другой стороны, есть избегание преждевременной... пессимизации. Когда вот у тебя есть инструментарий и вариант А и вариант Б. Вот они в целом одинаковые. Они с точки зрения когнитивного лода, с точки зрения readability, они одинаковые. Но этот намного лучше.

Ну, давайте тогда его использовать. Вот, и это как бы ноу-брейнер. Опять, это зависит сильно от системы контекста. То есть, например, там, насколько я помню, слышал в JetBrains, там, в корре шарпера, там забанен линк. Это что-то вот как streams в Java, такой high-level конструкции по работе. В Python это list comprehension называется. Он забанен, потому что там он фонит.

И в этом есть смысл, потому что там нет такого понятия, как преждевременная оптимизация. Это core очень-очень high performance sensitive системы. Там ты немножко по-другому смотришь на эти вещи. Если мы говорим о стандартном интерпрайзе, то там, наверное, будет совет не тупить. У тебя, очевидно, есть там... список какой-нибудь лукапа. Ты создал кэш, и этот кэш это не хэш-сет, это лист. И мы в другом цикле к нему обращаемся, и мы знаем, что там unbounded количество элементов.

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

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

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

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

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

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

Вот, но, да, то есть в не очень оптимизированной системе, ну, то есть здесь есть несколько моментов. Я хочу чуть-чуть уточнить этот по вот такой вот более low-hanging fruits kind of ситуации, что... Во-первых, эти low-hang foods, они зависят от use case. То есть у тебя, например, может быть новый use case в системе, который такой, о, брат, а теперь вот у нас оно теперь не работает.

Или оно работает, но очень плохо. Такой он пошел, посмотрел, при наличии телеметрии, профайлинга и так далее, выяснил, пофиксил. То есть это не то, что они фиксированы, или у тебя их проявление может быть самым разным. Не только баги в коде, не только увеличение лода, но и другие сценарии, которые есть. Другой сценарий, когда... То, что я называю, ну, часть людей называют death by a thousand cuts, когда у тебя явной проблемы нет, но у тебя есть overhead. Примеров может быть много.

Один из кейсов, который я нашел, вот когда я делал, добавил вот в эту вот систему кастомный string and turning, такой, о, блин, а какой компарер у строк надо добавить? Ну, по идее, ordinal. Ordinal или ordinal ignore case. То есть, ну... чтобы немножко контекста. У нас, когда строчки мы сравниваем на уникальность или на сабсеты, на вхождение, индексов и поиски и так далее, мы можем трактовать строку как бинарь или трактовать строку как бинарь, но ignore case.

Он очень эффективный, потому что там один битик надо убрать, и тогда у тебя в ASCII и в латинском алфавите маленькая буква А от большой буквы А отличается только взведенным каким-то шестым битиком или каким-то. То есть это можно сделать очень-очень быстро, case-in-sensitive, сравнение блобиков. Но если у нас-то есть там какое-нибудь турецкое i, да, которое, или там у нас просто букв явно больше, чем один байт, поэтому у нас есть локализированный поиск строк.

Вот там, culture aware. То есть я добавил такой, окей, у нас тут нет культуры, у нас нет UI, у нас будет ordinal. Ordinal ignore case. Или ordinal, не помню. Вот. И такой, дай я посмотрю, что мы используем. Он такой глянул, о, а у нас там хешсетов этих со строками. Вот так вот. И мы везде используем Ordinal Ignore Case. Такой, интересно, Ordinal Ignore Case. Подожди, подожди, подожди. А дай я запущу Benchmark и на каких-нибудь use-кейсах вот примерно сколько там элементов.

Ну, не знаю, может, 50-60. И посмотрю поиск и вставку, удаление, вот, примерно на моем хешсете или словаре, сколько это будет разницы между Ordinal и Invariant Ignore Case. Такой, о, в 10 раз. Твою мать, ничего. Я ожидал, что будет разница, но как бы не такая большая. Подожди, подожди, подожди. У нас этого много. Окей, хорошо. Find and Replace во всем проекте.

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

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

Я хотел рассказать пример, который недавно прочитал в твиттере, потому что, мне кажется, он тоже прикольный, как раз в эту степь падает. Чувак рассказывал, как оптимизировал, ну, там, прирост получил не очень большой, но 10% все равно неплохо. За счет чего? За счет того, что у него в одном месте использовались...

flatbuffers, честно, я с ними не работал, просто слышал, что это такая штука. Короче, в чем была проблема? Проблема в том, что в коде было две строчки. Сначала он кладет во flatbuffer key, потом он кладет value. И внезапно выяснилось, что в реализации, собственно, то, что пишется последним, вставится в начало записанного, стерилизованного потока данных, а вычитывается в обратном порядке. Сначала ключ, потом значение. В общем, он просто поменял местами две строчки.

Получил бесплатный прирост. И это такие вещи, которые, особенно если это делается во многих местах, ты этого не увидишь никак. Другой пример. У нас вот в билд-системе, в кэше, в сериализации, Кастомная, бинарная. В .NET используются там стандартные инструменты, там есть стримы, есть binary reader. В чем идея? То есть у тебя стрима это абстрактный класс, у нас полиморфизм, виртуальные вызовы.

И там на readbyte это как бы время. Вот. Мы переделали это. Там в новом .NET есть такая сверхклассная штука, называется спаны. Это такая себе абстракция над contiguous block of memory. То есть у тебя все, что угодно, что у тебя лежит в памяти, это может быть список, лист, unmanaged memory, вот это-то он. И вычитывание оттуда, это там highly inlineable и все остальное. И там в 10 раз разница.

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

То есть профайлер, он обычно тебе позволяет drill down ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, ниже, все мы делаем что-то полезное. И тогда можно задаться вопросом, А вот это вот все мы можем оптимизировать или нет? Если это вот в плане сериализации, то проще. В плане хэшсетов все равно не увидишь. Еще один пример.

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

Окей, хорошо. Уделение памяти, особенно если это какие-то бинари, то это означает, что мы ее выделили это время, ну, может, нормально. Потом мы ее делали, тоже должен. Потом мы скопировали, окей, хорошо. То есть это все какая-то работа. Можно посмотреть, если мы эту работу, можем ли мы ее выкинуть и не делать что-то. Ты выкинул здесь, там, там, там, там. Кумулятивно каждый из этих изменений будет там полпроцента или сколько. Сделать таких 10 изменений...

Оу, вау, окей, в сумме может быть там 10-15-20% прироста в throughput за счет уменьшения костов на какой-нибудь ерунде. То есть такие вещи... менее очевидные, они скорее делаются в более такой вот зрелой системе, где уже перформансом занимались. И здесь требуется определенная... Ведение, чуть-чуть интуиции, иногда пересмотр, какие инструменты у тебя есть, что они могут дать тебе. Как-то так. Так.

Про что? У меня есть один, который прямо рядом был. Давай. Я упоминал про вот эти вот спаны, и мы упоминали про прежневременную оптимизацию. Наверное, вот момент, который, насколько я помню, его задавали в телеге. Это про чистый код, абстракции и перформанс. Вот это вот очень интересная тема. Была война по поводу чистого кода versus перформанс. И, ну...

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

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

И вот спан этот в .NET, он есть в Rust, он есть в Go. Это в виде слайса какие-то. То есть все знают про итератор паттерн. То есть идея в том, что у нас есть коллекция, и она итерируема. И у коллекции есть базовый интерфейс. Например, в Дотнете это iNumorable. И опять...

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

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

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

Но с точки зрения реального железа это может быть на порядок отличаться. Потому что у тебя итерирование по массиву, у тебя все там локальность бла-бла-бла, а по линк-листу у нас прыгание по рандомной памяти. И там это для high-performance сценариев... Разница в 100 раз, извините, это важна.

И вот span в этом плане — это абстракция, которая практически не течет. Там есть какой-то очень хитрый corner case, потому что ты можешь использовать memory map file, получить pointer, и из pointer можно получить span, и тогда обращение по pointer будет там... Окей. Но в целом это почти не текущая абстракция. И это вещь, которая позволяет тебе универсальным образом работать с массивами, листами, unmanaged кодом и так далее. И вот...

С такой абстракцией ты можешь получить high-performance код. С innumerable, с которым ты не можешь даже рассуждать о том, а что это такое. ты high-performance код не получишь. И в этом плане я бы сказал, что для performance-sensitive кода важно обращаться с правильными абстракциями, которые не скрывают вещи, которые будут влиять очень сильно на perf-sensitive код.

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

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

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

Называется Mechanical Sympathy. Идея в том, что это чувак, который там занимался Формулой 1, он такой, блин, чтобы нам клево управлять машинами, нам нужно понимать, как они работают. И, наверное, вот...

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

Они могут двигаться между слоями абстракции достаточно свободно, когда ты делаешь Zoom Out и Zoom In. Когда мы смотрим на какую-то проблему, нам важно оперировать... терминами на определенном уровне. Иначе это будет невозможно. Модель OC, сетевая и все остальное, она важна. Мы говорим о HTTP, потому что это важно. Но, когда мы говорим о HTTP, это HTTP 1 или HTTP 2? Да, это с мультиплексингом или нет. А у нас TCP внутри. И дальше мы можем на определенном уровне.

То есть мы говорим о том, что у нас распределенная система использует gRPC, да? И потом ты можешь идти ниже. Окей, у нас какая сериализация? Такая, такая. Хорошо, нам это не важно. Потом, ага, это идет у нас HTTP 2 или 1? 1. Стоять мы уже

уткнулись. То есть вот эти вот возможности Zoom in, Zoom out на абсолютно разных уровнях это очень важная возможность. И в этом плане Zoom in, Zoom out в плане языков программирования тоже немаловажно. То есть вот у тебя есть В теории языкового программирования идея, не знаю, насколько она официальная или неофициальная, в C-Sharp это называется lowering, когда у тебя есть high-level конструкция, которая, по сути, потом трансформируется в low-level конструкцию.

Поэтому там, когда идут споры, а у нас for each или for loop, да, такой, ребят, твою мать. Оно просто тупо это одно и то же. То есть для компилятора это одно и то же. Давайте забудем о том, что вот у нас на LinkedIn все еще советы есть, что for each это плохо, да. Блин, это ужасно, это отвратительно, когда кто-то дает совет, как раз не понимая вот на этот уровень ниже. Просто, ну, абсурдный совет.

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

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

Мы ее делаем чехарду какую-то. Это не так, это не нужно. Мы можем сделать это в один этап и не делать этого. Эти шаги просто лишние. Сколько бы я не оптимизировал бэкэнд, я не могу узнать, что 90% запросов были лишние. И в этом плане очень важно как раз, почему мы говорили про C++ или C versus Java и C Sharp. Потому что это тебе иногда позволит оптимизировать, получить десятикратный прирост в перформансе, который ни один C...

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

То есть если ты не знаешь в принципе, что такое GC, то сложно себе увидеть, когда ты смотришь профайл. Ну, пример из недавнего опыта. У нас там есть какая-то библиотека для генерации темплейтов. Запускаем, смотрим в профайлере. Юзерского кода вообще нет. И у нас какие-то Локи, Локи, Локи, CLR, Локи. Такой, блин, что ж такое? Окей, там с другой стороны посмотрели. Такой, о, у нас кодогенерация включена. Хорошо, кодогенерация включена у этой библиотеки. Подожди, но она...

должна помогать, когда мы генерируем это изредка и потом реюзаем. Подожди, а мы эти темплейты, которые мы используем, мы их реюзаем? Нет, не реюзаем. Твою мать. Окей. То есть... Теперь в результате, в данном случае, понимание технологии, что кодогенерация, локи в дебрях CLR. это очень странно увидеть, мы потом делаем step back, step back, step back, и понимаем, что мы просто неправильно используем библиотеку. То есть в этом плане вот этот вот...

Кто-то называет mechanical sympathy. Но возможность перемещаться между уровнями абстракции просто абсолютно важно. И важно понимать...

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

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

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

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

Пример. Опять недавно в .NET комьюнити была такая буча, что где-то там на Reddit кто-то написал, что у нас в компании забанен линк. Это вот этот вот удобный лист Comprehension Syntax. Там он может быть в виде прям как SQL-like запросов, либо может быть как просто вызов методов. Забанен, все. СТО сказал, пришел, типа... Нет. И такой... Как он возникает?

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

Кроме вот этого полупроцента случая, когда он ненормальный. Плюс там есть способы, как его сделать быстрее, когда он будет выглядеть точно так же, но при этом под капотом будет другой код выполняться. Но иногда у тебя могло быть представление. Даже вот я говорил о том, что я поправил string and turning и сделал свой. В результате можно сказать, что никогда. Там, в принципе, наверное, есть рекомендация, которая, наверное, она разумная, что...

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

Вот. Ты всё-таки чётко. Да вот это там вся... Или там, о, Сергей сказал, что это нельзя. О, Сергей сказал, что это нельзя. О, тогда мы не будем использовать. Такие всё. И возникают правила какие-то. А потом, ну, там, опять же, string and turning, он потом, там, есть ahead-of-time компиляция, там он поправлен, он там быстрее, чем мой самописник. Это поправили.

Ты приходишь такой и везде тянешь свои вот кастомные решения, кастыли какие-то. А рантайм уже нормально работает. Или там у тебя в результате сложилось впечатление о перформанс характеристики чего-то. исходя из твоего старого опыта в старом контексте, и этот старый контекст может быть другой use case, другое время, другой runtime, еще что-то. Ты его транслируешь as is в новые контексты.

без переосмысления того, что подожди, а это точно проблема? А это вообще, ну первое это, а это вообще, блин, проблема или нет? Или мы пытаемся вот этот вот, вот один из, есть просто тьма искажений, один из них называется recency bias. То есть что-то, что произошло недавно, это, о, я помню, линк плохой, он, Сергей рассказывал, линк плохой. О, точно, точно, и я помню.

И тебе кажется, что это важно. И как мы принимаем решение? Мы же принимаем решение обычно эмоционально. Гайдлайн. Забаним. И все. И так это в плане перформанса. Померяй. Через метрика. Покажи, почему это важно, почему это не важно. Почему ты забанил линк, переписал его простым циклом, а ты просто его неэффективно этот метод в принципе вызываешь. Ты его вызываешь 10 миллионов раз, хотя это абсолютно не нужно. Вот, здесь...

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

«О, я слышал, тот сказал, вот это плохо». Поэтому вот такой вот пиар, мы поменяли такой, твою мать, как так-то? Мы там раскрывали словари в Key Value Piers и так далее. И опять же, без бенчмарков, без подтверждения того, что это нужно. Вот так это, и вот на моём, в моём случае, он вот был близко, то есть, будь у меня другой mindset, я говорю, блин, фиговая штука, баним. И мы можем написать линтеры, которые бы забанили это дело. Это абсурдно. Это...

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

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

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

Есть вот смежный вопрос. У меня его ребята, поскольку я делаю много довольно внутренних докладов, спрашивают, как ты учился. Вот, может быть, это будет следующим этим. Давай, давай. Давай с этого начнём. Они переплетены потом. в чем фишка. То есть, с одной стороны, опять, мы обещали, что не будет много .NET, но на самом деле этого достаточно. Ну, окей. Я надеюсь, что он достаточно agnostic.

В плане концепции, чтобы можно было ревизировать другие технологии в другие места. Слушай, мне примеры. Я на Дотнете никогда не писал. Собственно, C-Sharp даже близко не мой родной язык, но мне были примеры, понятно. Окей, то есть я буду использовать еще одного человека. Мне посчастливилось быть его ментией в прошлом году. Это Стивен Толб. Он опять люди, которые занимаются в дотнет-мире. Это прям...

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

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

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

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

Вот там пример, опять же, более наивный, более простой, но когда я делал доклад по поводу оптимизации первой системы, и там наш VP спросил, типа, а почему ты считал, что это можно сделать? Ну, я просто прикинул, что у нас нет ничего такого в... нашей области, что требует 400 гиг памяти. Ну нет такого. Или что требует 2 часа на стартап. Это мощнейшие 32-ядерные машины. Мы не можем стартовать 2 часа.

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

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

или Томас Мартин. Потрясные видео, они прям так озаглавлены, там, Design for Performance и все такое. И вот там пересекается с идеями, теми, о которых я говорю, но если посмотреть, они будут... И туда он копнул, и туда он копнул, и туда он копнул. Ты такой, твою мать, и обо всем этом надо знать. Да пошло оно. И, соответственно, если тебе это в целом интересно, ты будешь копать в эти куски довольно глубоко, у тебя будет куча дыр.

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

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

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

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

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

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

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

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

Сергей, спасибо тебе большое за то, что к нам пришел в гости. Спасибо, что позвали. Будь здоров. Надеюсь, в следующий раз ты к нам придешь не через 6 лет, а парниш. Зовите. Стас. Да-да. А можешь задать тебе вопрос? Конечно. Что тебе нравится больше, чем спустя без двух месяцев семь лет? позвать снова гостя на подкаст. И, наконец-то, это будет эпизод подкаста, на сей раз с более понятным названием.

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

Вот, да, больше этого, дорогие друзья, мне нравится, когда вы ставите 5 звезд в IT, все твитите, ретвитите, рассказывайте о нас своим друзьям, а самое главное, слушайте подкаст «Подлодка». Это был выпуск про хай-перформанс, оптимизацию. Мы еще подумаем, подумаем, да. На этом все. Спасибо, что нас слушали и смотрели. Всем пока-пока. Пока-пока.

This transcript was generated by Metacast using AI and may contain inaccuracies. Learn more about transcripts.