!Дисклеймер 1! речь именно о Golang, в других языках (например, Java) ситуация может быть абсолютно противоположной
!Дисклеймер 2! сказанное относится не ко всем типам данных Go, например, содержание slice (array / vector) само по себе является ссылкой, поэтому если вы их не копируете в явном виде, то они будут мутабельные
Есть 2 вида памяти: стэк (связанных список) и heap (граф)
Аллокация и освобождение данных в стэке – быстрые операции, потому что их не приходится искать, а вот для освобождения heap приходится использовать Garbage Collector (GC)
Как скорость, так и нагрузка при копирования и освобождения стэка может быть в десятки раз быстрее, чем этиже операции над heap (потому что GC приходится делать много дополнительных действий, чтобы понять пришло ли время освободить какой-либо кусок heap)
В Go можно передавать переменные по ссылке, а можно по значению (что создает их копию)
В ситуациях, когда какая-то переменная помещается в лимиты памяти стэка и не покидает его скоуп, Go старается аллоцировать переменную именно в стэке
Чаще всего, передача аргументов / возврата функции именно по значению (а значит копирование) даст понять Go, что этот кусок данных лучше положить в стэк
Тем самым копируемые (иммутабельные) структуры, чаще всего попадут в стэк, а значит и будут намного быстрее как аллоцированы, так и деаллоцированы
Круто
В
Вова хардвейр смартвенд
2023-10-23 09:23
Ты сейчас что-то про стек сказал, но по-моему это хрень. Какой нафиг связный список?
🦾
🦾 IT-Качалка Давида Шекунца 💪
2023-10-23 09:26
Ща я даже перепроверю, но суть в том, что Go выделяет стек на goroutine, а не на thread и способен его увеличивать фреймами по 2 / 4 /8 kb, причем ему не приходится увеличивать текущий фрейм, он просто ищет еще один свободный кусок в памяти, аллоцирует там еще проставрнство для фрейма и связывает с предыдущим, а после снятия фукцнии из стэка чистит конкретные отдельные фреймы
Поэтому стэк в го можно назвать связанным списком (как связи между фреймами, которые могут лежить непоследовательно)