Pull to refresh

Comments 11

Не совсем понял вопрос в названии статьи. И не нашел ответа на него. Да, можно или нет, нельзя. А если не всё так однозначно, то зачем так взаимоисключающе был поставлен вопрос?

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

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

К кому вопросы, если статья — это просто перевод

Хорошая статья, по идее, каждому разработчику на том или ином компилируемом ЯВУ стоит ознакомиться с возможностями его компилятора, по достижению некоторого уровня в разработке. Так мое знакомство с компилятором Go показало, что большая часть Solid и пр. Энтерпрайз рекомендаций им или не поддерживается или поддерживается "из рук вон плохо", по крайней мере до версии 1.20, дальше не смотрел.

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

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

нет на примете годного материала про проблемы инлайнинга в го?

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

func notInlined(m sync.Mutex){
  m.Lock()
  defer m.Unlock()
  var a = 1
}

Уже НЕ инлайнится "по определению". А Функция:

func inlined(m sync.Mutex){
  m.Lock()
  var a = 1
  m.Unlock()
}

Инлайнится.

А теперь, представьте себе типовой "Энтерпрайз", где есть структура данных с мьютексом, ибо разделяется в горутинах и .. геттеры, сеттеры, что-то посеръезнее .. всё обрамлено первым вариантом.. особенно в "многослойных" архитектурах по "дяде Бобу" :(

И это мелочи. Точно также не инлайнятся:

Однократно вызываемые функции и методы, если они под капотом содержат больше 2-4 строк кода (действий);

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

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

Я так понимаю там не настоящий инлайнинг, а что то ну... Go шное

Там компилятор "го..ный" ;) "Ну не шмогла я!" (с) бородатый анекдот..

Хорошая статья.

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

А если бы ещё умные встроенные инструменты могли анализировать потенциал возможностей более сильной оптимизации и выдавать об этом подсказки (связанные с изменениями в коде, как прямыми, так и, например, через какие-то явные хинты для компилятора) - то это было бы ещё круче!

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

Советы компиляторы уже дают, в godbolt для Clang есть окно Optimization (через кнопку +).

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

( https://habr.com/ru/articles/685228/ )

Sign up to leave a comment.