Los hashes son el tipo de objeto que más memoria consume en las aplicaciones Ruby, muy por encima de alternativas como Struct o los llamados PORO (Plain Old Ruby Objects). Un hash vacío ocupa 160 bytes en Ruby 4.0.6, hasta cuatro veces más que un Struct del mismo tamaño, una diferencia que se mantiene en rangos de 2x a 4x según el número de claves.
Este artículo analiza la evolución histórica de la implementación interna de los hashes para explicar ese sobrecoste. En Ruby 2.3 un hash de una clave consumía 232 bytes, frente a los 160 bytes actuales, tras dos grandes reformas. La primera llegó con Ruby 2.4, cuando Vladimir Makarov sustituyó la tabla hash tradicional por direccionamiento abierto (open addressing), una técnica que mejoró la velocidad pero увеличил el tamaño de la cabecera C de 48 a 56 bytes.
La segunda reforma llegó con Ruby 2.6, cuando Yimin Zhao, dentro de un Google Summer of Code tutorizado por Koichi Sasada, integró los hashes con el "transient heap" (montículo transitorio), un asignador con puntero de incremento pensado para objetos de vida corta que reduce la presión sobre malloc durante los ciclos de petición o trabajo. Tras el marcado del GC, los objetos supervivientes se reasignan con malloc real y el montículo transitorio se vacía para reutilizarse.
El texto, aunque centrado en diagnóstico e historia, deja una recomendación práctica: allí donde sea viable, conviene sustituir los hashes por Struct o PORO para reducir el uso de memoria, ya que la mejora acumulativa entre Ruby 2.3 y 4.0 no elimina el desfase frente a las estructuras más ligeras.
