Acelerando los hashes pequeños de Ruby con búsqueda SWAR

Fuentes: Speeding Up (small) Ruby Hashes

Ruby no implementa sus hashes pequeños como tablas hash propiamente dichas: cuando un objeto Hash tiene ocho entradas o menos, su clase lo representa internamente mediante una estructura llamada ar_table, que en esencia es un array plano de pares clave-valor más un array de hints (el byte bajo del hash-code de cada clave). El acceso en ar_table es, por tanto, una búsqueda lineal O(n), algo que se puede confirmar experimentalmente con benchmark/ips: consultar la primera clave ronda los 14,18 millones de iteraciones por segundo, mientras que la octava cae hasta unos 8,98 millones, una diferencia aproximada de 1,58 veces. Pese a ello, en la práctica esa búsqueda lineal no queda muy lejos del rendimiento de un Hash respaldado por una st_table (la implementación hash real de Ruby), con una diferencia de apenas 1,18 veces en favor de la tabla hash, lo que revela un compromiso clásico entre espacio y tiempo.

El artículo plantea la posibilidad de convertir esa búsqueda en O(1) mediante SWAR (SIMD Within A Register), una técnica que aprovecha el ancho de los registros del procesador para comparar varios bytes en paralelo dentro de un único valor de 64 bits. Como ar_table guarda únicamente ocho hints de un byte, caben exactamente en un registro y pueden explorarse de forma simultánea con operaciones bit a bit, evitando recorrerlos uno a uno. Se trata de una continuación directa de un análisis previo sobre cómo Ruby encoge sus hashes y abre la puerta a optimizaciones internas del intérprete que pueden acelerar millones de lookups sin cambiar la API pública del lenguaje.