Polimorfismo Dinámico vs. std::variant: Desmitificando Mitos sobre la Velocidad de std::visit

Explorando las ideas erróneas sobre el polimorfismo dinámico y std::variant en C++.

5 min readProgramación

En el ámbito del C++ moderno, ha surgido una creencia común: el polimorfismo dinámico tradicional a través de funciones virtuales se considera obsoleto e ineficiente, especialmente en lo que respecta a la amigabilidad con la caché del CPU. Los defensores a menudo proponen el uso de std::variant junto con std::visit como una alternativa superior. Muchos artículos circulan en línea afirmando que std::visit logra la despachación en tiempo constante O(1), lo que efectivamente hace que la programación orientada a objetos clásica quede obsoleta. Sin embargo, estas comparaciones a menudo caen en errores metodológicos, contrastando un vector de punteros (std::vector<Base*>) con un vector de objetos en bruto (std::vector<std::variant>). Aunque std::variant puede parecer sobresalir, esta ventaja proviene no de la mecánica de las llamadas a funciones, sino de su localidad de datos dentro de la caché del CPU. Para aclarar esto, debemos igualar las condiciones y aislar la mecánica de las llamadas. Consideremos un escenario realista donde los objetos son pesados, se crean dinámicamente a lo largo del tiempo y están dispersos en el montón, mientras operamos en arreglos de sus direcciones. Compararemos directamente std::vector<Base*> con std::vector<std::variant<TypeA, TypeB, TypeC>*> en condiciones de compilación separada, donde el optimizador no puede aplicar la inlining total.

Programación