@nakem

Является ли передача переменной по указателю затратной операцией?

Недавно я узнал, что в некоторых случаях передача переменной в функцию по указателю может быть более трудозатратной операцией, чем по значению. Это все из-за escape-анализа. Если честно я вообще не очень понимаю как это работает, просто знаю, что этот анализ нужен сборщику, чтоб считать анализировать видимость указателей или что-то такое. Я узнал об этом особенности из доклада здесь прыжок на хабр
Так вот. Если в си\с++ мы можем просто передать указатель на сколь угодно огромный объект и эта операция произойдет мгновенно, то можем ли мы также делать в го? Я имею в виду, возможно, при адекватных размерах структуры этот escape-анализ очень быстро работает и можно даже не задумываться об этом, а может все-таки это стоит что-то и лучше избегать лишних передач переменных.
  • Вопрос задан
  • 138 просмотров
Пригласить эксперта
Ответы на вопрос 2
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
Я видел эти же или похожие бенчмарки, которые приведены в этой статье, год или два назад.
Тут важно отметить, что методика тестирования в статье не учитывает очень важный момент - там передача значения происходит всего один раз, т.е. функцию вызвали один раз и на том всё.

Но часто бывает так, что данные приходится передавать многократно.

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

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

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

Но если эти данные нужно будет передавать во много разных функций - то в большинстве случаев передача через указатель будет быстрее, даже с учётом того, что garbage collector это ресурсоёмко.
Ответ написан
Комментировать
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
В Go все параметры передаются функции копированием. То есть функция не может изменить оригинал аргумента, а работает с копией. Если вы хотите его в функции изменять у вас есть два варианта
  • передавать ссылкой, тогда функция может поменять значение по переданному адресу
  • или возвращать значением

func myFunc(arg type) type
...
bigArg = myFunc(bigArg)

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

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

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