El artículo "Nobody ever got fired for using a struct" explora un problema de rendimiento inesperado en Feldera, una plataforma que procesa datos SQL. La plataforma convierte tablas SQL en structs de Rust para su procesamiento incremental. Inicialmente, los structs parecen una solución ideal: son simples, rápidos y predecibles. Sin embargo, cuando se utilizan con grandes conjuntos de datos, especialmente aquellos con muchas columnas opcionales, pueden surgir problemas de rendimiento.
El problema radica en la forma en que Rust y la biblioteca de serialización rkyv manejan los Option<T> (tipos opcionales) dentro de los structs. Normalmente, Rust puede optimizar el almacenamiento de Option<bool> sin costo adicional, utilizando un valor especial para representar None. Sin embargo, cuando se utiliza rkyv para serializar los structs para su almacenamiento en disco, cada campo opcional se convierte en Archived<Option<T>>. ArchivedString, un tipo usado dentro de Archived<Option<SqlString>>, utiliza una representación 'inline' para cadenas cortas, lo que elimina la capacidad de Rust de optimizar el almacenamiento de None para Option<T>. Esto significa que cada Option ahora requiere un discriminador explícito, aumentando significativamente el tamaño del struct serializado.
El problema se agrava con structs que tienen cientos de campos opcionales, como los generados a partir de tablas SQL con muchas columnas nullable. Aunque la representación en memoria de un solo struct puede no ser un problema, la acumulación de estos structs serializados durante el procesamiento de grandes conjuntos de datos puede generar una sobrecarga significativa en el rendimiento, especialmente durante la escritura en disco. El artículo ilustra esto con un ejemplo de un struct con más de 700 campos, muchos de los cuales son opcionales.
En resumen, aunque el uso de structs es una práctica común y generalmente eficiente en Rust, su uso con grandes conjuntos de datos y estructuras complejas, especialmente cuando se combinan con serialización, puede llevar a problemas de rendimiento inesperados debido a la forma en que se manejan los tipos opcionales. La solución implica reconsiderar el diseño de las estructuras de datos o explorar alternativas a la serialización rkyv para optimizar el tamaño y la eficiencia de los datos serializados.
