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

У меня есть такая функция:

func New() *Foo{
    f := &Foo{}
    f.Init()
    return f
}

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

0
KamLar 16 Ноя 2021 в 02:38
1
Я помню, что бюджет выражения был 40. Как бы то ни было, прагма //go:inline была предложена и отклонена. Связанная проблема: github.com/golang/go/issues/21536
 – 
blackgreen
16 Ноя 2021 в 03:26
1
"Компилятор Golang": язык называется Go, и существует несколько компиляторов Go, среди которых наиболее известные - gc и gcc. Не существует такого понятия, как «компилятор Go».
 – 
Volker
16 Ноя 2021 в 08:22
Бюджет составляет 80, и он поступает от github.com/golang/go/blob/master/src/cmd/compile/internal/… - и я считаю, что мой случай другой, потому что OP из github хотел встроить все, что невозможно ( например: defer) - а я спрашиваю только о функциях, которые не встроены из-за размера бюджета. Хорошо, у Go есть несколько компиляторов, но, насколько я знаю, каждый из них реализует встроенные программы одинаково (по крайней мере, каждый из наиболее используемых, использует бюджет). Так что я думаю, нет необходимости указывать, какой именно. Может, мне не стоит использовать the - вы правы.
 – 
KamLar
16 Ноя 2021 в 14:54

1 ответ

Лучший ответ

Как вы поняли, краткий ответ - «нет, не без модификации компилятора», но это, вероятно, изменится в будущем. Uber работал над оптимизацией на основе профиля и сегодня опубликовал запрос на вытягивание, содержащий эту работу. Это займет немного времени, чтобы переварить (я работаю над компилятором, мы пытаемся собрать все наши утки подряд для выпуска 1.18, который велик, потому что он содержит общие шаблоны ), но это с уверенностью сказать, что мы заинтересованы. Скорее всего это может появиться в версии 1.19, которая запланирована на 8 месяцев с сегодняшнего дня.

В зависимости от причины замедления, может быть выгодно отметить f.Init() //go:noinline, что затем позволяет встраивать New в вашем примере. Если это выделение не попадает в кучу в вызывающей программе, то выполнение этого встроенного (вместо встраивания f.Init()) предоставляет возможность выполнять выделение стека, и таким образом вы можете сэкономить некоторое время. Обязательно отметьте «noinline» комментарием, объясняющим, почему вы это сделали :-).

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

1
David Chase 20 Ноя 2021 в 01:44
Вау, я только что узнал о дженериках из этого комментария, интересно!
 – 
suddjian
20 Ноя 2021 в 01:49