Rendimiento comparar (función de llamada normal vs for_each + mem_fun vs expresión lambda) en C ++

StackOverflow https://stackoverflow.com/questions/4366487

Pregunta

¿Cuál es la mejor (en el rendimiento) entre estos fragmentos?

1)

for(list<Enemy*>::iterator iter = enemies.begin(); iter != enemies.end(); iter ++)
   (*iter)->prepare(time_elapsed);

2)

for_each(enemies.begin(), enemies.end(), [time_elapsed] (Enemy *e) {e->prepare(time_elapsed);});

3)

for_each(enemies.begin(), enemies.end(), bind2nd(mem_fun1<void, Enemy, GLfloat>(&Enemy::prepare), time_elapsed));
¿Fue útil?

Solución

Lambdas son la solución más rápida. Hay optimizaciones especiales involucradas con la toma referencias a variables basados ??en la pila. Además, en C ++ 0x, son mucho más flexible que cualquiera de esas cosas se unen, y el primer bucle también tiene la desventaja de claridad. Lambdas son el winrar en todos los sentidos.

Sin embargo, estoy pensando seriamente micro-optimización, a menos que sea en un bucle muy, muy interno que se ejecuta mil millones de veces.

Otros consejos

2 y 3 son esencialmente idénticas. 1 podría ser más rápido, ya que realiza una llamada a la función por iteración mientras que 2 y 3 realizan dos llamadas a la función por iteración. Por otra parte algunas de las llamadas de función podría obtener inline. La única manera de realmente decir es medir.

Además, dado que usted está lanzando en las funciones lambda (C ++ 0x), por qué no añadir gama basada en bucles de sus medidas:

for (var iter : enemies) { iter->prepare(time_lapsed); }

asumiendo su compilador compatible con ellas, por supuesto.

EDIT: acabo de notar la etiqueta de VC ++ 2010. Por desgracia, su compilador no es compatible aún ellos: - (

Hice los measurations sin optimizaciones del compilador:

2) y 3) tienen casi el mismo tiempo de funcionamiento, en lugar 1) es 10 veces más lento. Añadí también un 4)

for each (Enemy* e in enemies)
      e->prepare(time_elapsed);

válido para Visual C ++ 2010 y debe ser el mismo sematically de Ferruccio de:

for (var iter : enemies) { iter->prepare(time_elapsed); }

4) es también casi tan rápido como 2) y 3).

Con -O2 todos tienen casi el mismo tiempo de ejecución.

La respuesta es "no es importante en absoluto hasta que haya medido que algo esta actualmente no lo suficientemente rápido ". Esta pregunta es esencialmente la optimización prematura. Hasta que de demasiado lento y has medido el bucle de ser un cuello de botella, su prioridad es utilizar el código que comunica lo que estamos tratando de hacer en la forma más clara . código de buena escritura en primer lugar, optimizar la tarde.

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