Este artículo del blog de Go explica cómo los desarrolladores están optimizando el rendimiento de Go al realizar más asignaciones de memoria en la pila (stack) en lugar del montón (heap). Las asignaciones en el montón son costosas, requieren código adicional y generan carga para el recolector de basura (garbage collector), incluso con mejoras recientes como Green Tea. La pila, por otro lado, ofrece asignaciones más rápidas (a veces gratuitas), no impactan al recolector de basura y permiten un mejor aprovechamiento de la caché.
Inicialmente, el problema se identificó en la creación de slices. Cuando se construye una slice iterando sobre un canal, cada append puede generar múltiples asignaciones de memoria en el montón a medida que el slice crece. Una solución simple es inicializar la slice con una capacidad predefinida (make([]task, 0, 10)), lo que puede reducir significativamente las asignaciones. Sorprendentemente, en algunos casos, esto puede incluso eliminar las asignaciones por completo, ya que el compilador puede asignar el almacenamiento en la pila si el tamaño es conocido y no 'escapa' a la función.
Go 1.25 introdujo mejoras automáticas: el compilador ahora puede asignar el almacenamiento de la slice en la pila si se proporciona una estimación de la longitud (lengthGuess) y esta estimación es lo suficientemente pequeña (menos de 32 bytes). Esto elimina la necesidad de código adicional para forzar la asignación en la pila. Además, Go 1.26 lleva esta optimización un paso más allá, permitiendo que incluso las asignaciones realizadas directamente en el append se realicen en la pila, evitando la sobrecarga inicial de asignaciones del montón. Esto es especialmente útil cuando la slice se devuelve de una función, aunque en ese caso, la asignación en la pila no es posible porque el frame de la pila desaparece al retornar.
En resumen, las versiones recientes de Go están optimizando automáticamente la asignación de memoria, priorizando la pila siempre que sea posible para mejorar el rendimiento y reducir la carga del recolector de basura. Los desarrolladores pueden beneficiarse de estas mejoras simplemente actualizando a las últimas versiones de Go y, en algunos casos, proporcionando una estimación razonable de la longitud de las slices.
