Pregunta

Por motivos de rendimiento, estoy usando el patrón Curiosamente Plantilla Reoccuring para evitar funciones virtuales. Tengo un montón de pequeños comandos que se ejecutan millones de veces. Estoy tratando de encajar esto en el patrón de comando. Quiero añadir toneladas de comandos a una cola, y luego iterar a través de ellos la ejecución de cada una por una. Cada comando utiliza un CRTP para evitar funciones virtuales. El problema que estoy en es que el patrón de comando se implementa típicamente usando un vector de punteros. Pero cuando la clase Command es de plantilla, se hace difícil para pasar alrededor de los punteros de comandos genéricos. No soy experto en C ++, así que quizás hay una manera obvia para almacenar un vector de objetos de comando con plantilla? He estado tratando de usar algo como:

boost:ptr_vector commands;
AddCommand(Command* command) {
  commands.push_back(command);
}

El problema es Command no es un tipo, por lo Command* command da un error de compilación. Necesito usar Command<CommandType>, pero eso no va a funcionar porque necesito la cola para contener diferentes tipos de comandos.

Todas las ideas para las soluciones? O son funciones virtuales mi única opción?

AÑADIDO: Los objetos de comando son parte de un algoritmo de simulación de Monte Carlo. Lo que podría tener, Comando ser un número al azar de una distribución normal, donde los parámetros de la distribución normal son parte de la clase. Por lo que el patrón de comando se adapta muy bien. Tengo un montón de llamadas, en un orden particular, a las funciones que necesitan para mantener el estado.

¿Fue útil?

Solución

El CRTP hace su magia por resolver el tipo de tiempo de ejecución del objeto en tiempo de compilación para que el compilador puede inline las llamadas a funciones. Si usted tiene un vector de punteros a un tipo genérico, el compilador no puede determinar el tipo específico concreto, y no será capaz de hacer su resolución en el tiempo de compilación.

A partir de sólo la información que tiene en su pregunta, creo que las funciones virtuales son su mejor opción. Sin embargo, las funciones virtuales no son tan lento. Ellos son más lentos que una función de forrado, seguro, pero en muchos casos son lo suficientemente rápido! Especialmente si el proceso está limitado por el tiempo de E / S en lugar de tiempo de procesamiento.

una de las respuestas a esta pregunta tiene alguna discusión más profunda de este tema. Para resumir, la sobrecarga para una llamada de función virtual es probable que se mide en nanosegundos. Es más complicado que eso, pero el punto es que usted no debe tener miedo de las funciones virtuales a menos que su función es hacer algo muy trivial como una sola tarea. Usted ha dicho que sus órdenes eran pequeños, por lo que tal vez este es el caso. Que iba a tratar de hacer un prototipo rápido con funciones virtuales y ver si eso le da un rendimiento aceptable.

Otros consejos

A menos que usted está construyendo su cola de comandos durante el tiempo de compilación, lo que quiere es imposible.

No puedo decir si su cola de comandos cambia con frecuencia o rara vez.

Si se cambia rara vez, en comparación con la frecuencia con que se ejecuta, me parece que esto podría ser un trabajo para la generación de código.

Sólo imprimir un programa para hacer las acciones que necesita, compilar y vincular un DLL sobre la marcha, y cargarlo. Esto debería tomar alrededor de un segundo. Sin clases, objetos, o de despacho. Y si solo paso que, verá casi no hay ciclos que no contribuyen significativamente a la respuesta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top