2011-08-26 12 views
7

Hace poco, encontré ese artículo muy interesante sobre una actualización de rendimiento muy clara para dynamic_cast en C++: http://www2.research.att.com/~bs/fast_dynamic_casting.pdf.Avance rápido de fundición dinámica

Básicamente, hace dynamic_cast en C++ mucho más rápido que la investigación tradicional en el árbol de herencia. Como se indica en el documento, el método proporciona un algoritmo de lanzamiento dinámico rápido y de tiempo constante.

Este documento se publicó en 2005. Ahora, me pregunto si la técnica alguna vez se implementó en alguna parte o si hay planes para implementarla en cualquier lugar.

+1

No sé si algún compilador lo usa, pero lo he visto utilizado en un par de soluciones RTTI basadas en bibliotecas. –

+0

Dado que la "asignación" del "tipo ID" se realiza durante el tiempo de enlace (ver el documento), ¿cómo puede una biblioteca lograr eso? ¿Tienes un ejemplo? –

+0

No es exactamente lo mismo; las ID se asignan a través de algún otro método, pero todavía usan módulo para determinar un lanzamiento válido. –

Respuesta

7

No sé qué implementaciones usan varios compiladores al lado de GCC (que no es lineal). Sin embargo, es importante destacar que el documento no necesariamente propone un método que siempre es más rápido que las implementaciones existentes para todo (o incluso común) uso. Propone una solución general que es asintóticamente mejor a medida que crecen las jerarquías de herencia.

Sin embargo, rara vez es un buen diseño tener grandes jerarquías de herencia, ya que tienden a forzar a la aplicación a ser monolítica e inflexible para cambiar. Los programas con diseño flexible tienden a tener jerarquías principalmente con 2 niveles, una base abstracta y una implementación de roles polimórficos en tiempo de ejecución para soportar el Principio Abierto/Cerrado. En estos casos, recorrer el gráfico de herencia puede ser tan simple como una referencia y desreferencia de un solo puntero, que puede ser más rápido que el índice-suma-entonces-desreferencia-luego-comparación presentado por Gibbs y Stroustrup.

Además, es importante destacar que es nunca necesario para escribir un programa que utiliza dynamic_cast a menos que las reglas de su propia empresa así lo requieran. El uso de dynamic_cast es siempre una indicación de que el polimorfismo no se usa correctamente y la reutilización se ve comprometida. Si necesita un comportamiento basado en la creación de una jerarquía, agregar un método virtual brinda la solución limpia. Si tiene una sección de código que hace dynamic_cast-cheques en los tipos, esa sección de código nunca se "cerrará" (en el sentido del Principio Abierto/Cerrado), y deberá actualizarse para cada nuevo tipo agregado al sistema. Por otro lado, un despacho virtual se agrega solo a los nuevos tipos, lo que le permite permanecer abierto a la expansión y, a la vez, cerrar los comportamientos que operan en el tipo base.

Esto es realmente una sugerencia más bien académica (que equivale a cambiar algorítmicamente un mapa a un hash_map) que no debería tener efectos en el mundo real si se sigue un buen diseño. Si las reglas comerciales prohíben el buen diseño (algunas tiendas pueden tener barreras de código o problemas de propiedad del código donde no se pueden cambiar las arquitecturas existentes de la manera que necesitan, ni se pueden construir adaptadores como se usaría comúnmente para bibliotecas de terceros), entonces es mejor no tomar la decisión sobre qué compilador utilizar en función de qué algoritmo se implemente. Como siempre, si el rendimiento es clave y tiene que usar una función como dynamic_cast, perfile su código. Es posible (y probablemente en muchos casos) que la implementación de caminar sobre los árboles sea más rápida en la práctica.

Véase también the standards committee's review of implementations, including dynamic_cast y a well-known look at c++ in embedded environments and good use (which mentions Gibbs and Stroustrup in passing).

+0

No soy un fanático de dynamic_cast, pero hay situaciones (generalmente debido al uso de lib de terceros o "hacks" de lenguaje) donde es necesario. No es la primera vez que leo que dynamic_cast es señal de un mal diseño y que el mismo comportamiento podría haberse hecho de otra manera, pero me gustaría tener una "prueba" de esa declaración o al menos algunos consejos ... –

+0

El reparto dinámico proporciona acceso a un tipo convertible y un punto de ramificación para una ejecución condicionada. La prueba estándar muestra que un despacho virtual proporciona las mismas características, por lo que cualquier llamada "if (dynamic_cast <...> (...)) se puede convertir a despacho virtual simplemente implementando el comportamiento en una función virtual. Una prueba extendida generalmente indica que las bibliotecas de terceros se pueden usar de manera similar al proporcionar clases de contenedor para la jerarquía, con el comportamiento previsto. Esa transformación muestra que no se requiere acceso a la implementación. – ex0du5

Cuestiones relacionadas