Комментарии 11
Не совсем понял вопрос в названии статьи. И не нашел ответа на него. Да, можно или нет, нельзя. А если не всё так однозначно, то зачем так взаимоисключающе был поставлен вопрос?
Компиляторы — это инструменты. Несмотря на то, что иногда происходит изрядная доля “оптимистичных” преобразований, основная часть воздействия оптимизирующего компилятора достигается за счет гарантированной оптимизации с определенными предварительными условиями.
И считаю, что зря вы взяли в кавычки слово - "оптимистичных” преобразований. Компиляторы заслуживают того, чтобы оценить их оптимистический подход к компиляции кода. Оптимизацию делают и они, и операционная система, и процессор.
Хорошая статья, по идее, каждому разработчику на том или ином компилируемом ЯВУ стоит ознакомиться с возможностями его компилятора, по достижению некоторого уровня в разработке. Так мое знакомство с компилятором Go показало, что большая часть Solid и пр. Энтерпрайз рекомендаций им или не поддерживается или поддерживается "из рук вон плохо", по крайней мере до версии 1.20, дальше не смотрел.
В частности, Вы правы: функция - единица компиляции, причем достаточно сложная, ибо есть "подготовительный вход в функцию", процесс передачи параметров, построение выброса исключений, и обратный процесс возврата результа, восстановления контекста (выход) и пр. Инлайнинг тянет за собой много "дурного кода", который компиляторы умеют выбрасывать.
К сожалению, требование уменьшения размера функций в энтерпрайз (один метод - одно действие, часто тривиальное, с расширенным наследованием и разделением труда) упирается в .. ограниченный инлайнинг компилятора Go, но .. про это мало где можно прочитать в хвалебных одах языку, увы. Часто только копание в потрохах и тестах позволяет обнаруживать проблемы.
нет на примете годного материала про проблемы инлайнинга в го?
В языке есть понятие 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 анализ, который Вам всё это выдаст на гора.. смотрел и дивился. В нем же можно посмотреть как легко локальные переменные, параметры уплывают в кучу "на ровном месте".
Тэг/хаб C++ лучше убрать - нет тут такого.
Хорошая статья.
Вот подумал - наверное этого не хватает в IDE (ну и со стороны оптимизирующих компиляторов должна быть соответствующая поддержка) - а именно: возможности видеть где какие оптимизации применены (или будут применены) хотя бы в общих чертах. Не думаю, что это большая проблема сделать такую визуализацию - речь даже не про финальный код - а просто хотя бы расставить пометки классификации применения той или иной оптимизации. Ну ведь некоторые IDE помечают сейчас, скажем, не используемые локальные переменные или лишние присвоения. Вот и тут можно было бы помечать чуть больше - наверное в отдельно включаемом режиме отображения кода, ну, или хотя бы, в отдельном инструменте анализа кода - в результирующем отчёте.
А если бы ещё умные встроенные инструменты могли анализировать потенциал возможностей более сильной оптимизации и выдавать об этом подсказки (связанные с изменениями в коде, как прямыми, так и, например, через какие-то явные хинты для компилятора) - то это было бы ещё круче!
Ну а если ещё и автотесты разных версий оптимизаций система умела бы делать и выдавать с рекомендациями (а так же по фактически сделанным оптимизациям) - оценку эффективности повышения производительности - то вообще было бы очень круто! Вот, к примеру, видит оптимизатор, что есть потенциал к ускорению, но есть "тёмные", "неоднозначные" места или ещё какие-то части кода, которые потенциально можно было бы улучшить - но не без контроля или даже переделки со стороны программиста - вот тогда она могла бы его об этом проинформировать, вместе, с оценкой потенциальной выгоды - а уже программист бы сам решал, стоит ли овчинка выделки, и тратить ли силы на переписывание кода (в чём ему IDE тоже должна оказать посильную реакторную помощь). Тут нужно активно опираться на базу готовых решений, так и собирать статистику тестовых прогонов текущего кода
Можно ли доверить компилятору оптимизацию вашего кода?