@iliyaisd

Стоит ли избегать знака присваивния := в Go при нагруженном бекенде?

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

Спасибо.
  • Вопрос задан
  • 864 просмотра
Пригласить эксперта
Ответы на вопрос 2
Tyranron
@Tyranron
Это неважно.
Не следует "экономить на спичках" и соблюдать пустые ритуалы. Вы пишите приложение нормально, чтобы его понимали и нормально читали другие разработчики. Когда же дело доходит до оптимизации, Вы профилируете и смотрите где конкретно у Вас проблемы и затыки. Их и убираете.

Что же касается конкретно аллокаций, то всё не совсем так (вернее, совсем не так).
Аллокация - это выделение куска памяти в куче (heap), который потом должен быть убран сборщиком мусора. Именно потому это и считается ударом по производительности, так как добавляет работы как аллокатору, так и сборщику мусора.
Но использование := само по себе не включает/выключает использование аллокации. Оно лишь декларирует новую переменную.
Будет ли произведена аллокация зависит от другого. В первую очередь, от того какие Вы данные создаёте. Если это примитивный тип фиксированного размера, размещаемый на стэке (например int), то работы с кучей у Вас не будет вовсе, соответственно и аллокаций. Во вторую очередь, от такой магической штуки как escape analysis, которая может запросто разместить данные из кучи на стэке, если ей так того захочется, тогда аллокации у Вас происходить тоже не будет.

Давайте посмотрим примеры:
  1. var i int
    i = 1
    i = 2

    0 аллокаций, так как i размещается строго на стэке.

  2. i := 1
    i := 2

    0 аллокаций, так как i размещается строго на стэке.

  3. i := new(Struct{1,2,3})
    i := new(Struct{3,2,1})

    2 аллокации, так как new разместит данные в куче и вернёт указатель на них. Но только если escape analysis не переместит это всё в стэк (что конкретно в данном случае достаточно вероятно).

  4. var i *Struct
    i = new(Struct{1,2,3})
    i = new(Struct{3,2,1})

    2 аллокации, так как new все ещё разместит данные в куче и вернёт указатель на них.



Как Вы видите, := сам по себе никак к аллокациям не относится, и является лишь синтаксическим сахаром.

P.S. Давеча на Хабре была отличнейшая статья про стандартную библиотеку Go, показывающая что занятие преждевременными микрооптимизациями без профилирования - вполне себе бессмысленная затея.
Ответ написан
Комментировать
@golangmoses
используйте sync.Pool
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы