Por ejemplo, tengo el siguiente código:
auto z = [](int x) -> int {
if (x > 0) {
switch (x) {
case 2: return 5;
case 3: return 6;
default: return 1;
}
}
return 0;
};
Y luego llamo a esto varias veces. En el código asm veo llamadas externas con lambda ... algo ... No se está volviendo fácil de leer y creo que también puede causar rendimiento. Entonces, tal vez gano en metaprogramación, pero ¿pierdo en depuración y rendimiento de asm? ¿Debo evitar las características del lenguaje moderno, las macros y otros aspectos de meta programación para asegurarme de la simplicidad de depuración y rendimiento?
if
es completamente redundante en el código de ejemplo, y aunque el compilador probablemente se dará cuenta de que no hay razón para tentar una predicción de rama incorrecta.Respuestas:
No , no cuando escribe su código la primera vez y no sufre ningún problema de rendimiento real y medible. Para la mayoría de las tareas, este es el caso estándar. Pensar demasiado pronto sobre la optimización se llama "optimización prematura", y hay buenas razones por las cuales D. Knuth lo llamó "la raíz de todo mal" .
Sí , cuando mide un cuello de botella de rendimiento real y demostrable, e identifica esa construcción lambda específica como la causa raíz. En este caso, puede ser una buena idea recordar la "ley de las abstracciones con fugas" de Joel Spolsky y pensar en lo que podría suceder a nivel asm. Pero tenga cuidado, es posible que se sorprenda de lo pequeño que será el aumento del rendimiento cuando reemplace una construcción lambda por una construcción de lenguaje "no tan moderna" (al menos, cuando se utiliza un compilador decente C ++).
fuente
La elección entre lambda y functor-class es una compensación.
La ganancia de lambda es principalmente sintáctica, al minimizar la cantidad de repeticiones y permitir que el código relacionado conceptualmente se escriba en línea, dentro de la función que lo va a utilizar (inmediatamente o más tarde).
En cuanto al rendimiento, esto no es peor que una clase functor , que es una estructura o clase C ++ que contiene un solo "método". De hecho, los compiladores tratan la lambda de manera diferente a una clase de functor generada por el compilador detrás de escena.
En su ejemplo de código, en cuanto al rendimiento, no es diferente de una llamada de función, porque esa clase de functor no tiene estado (porque tiene una cláusula de captura vacía), por lo que no requiere asignación, constructor ni destrucción.
La depuración de cualquier código C ++ no trivial utilizando un desensamblador siempre ha sido una tarea difícil. Esto es cierto con o sin usar lambda. Esto es causado por la sofisticada optimización de código del compilador de C ++ que resultó en la reordenación, intercalación y eliminación de código muerto.
El aspecto de cambio de nombre es algo desagradable, y el soporte del depurador para lambda todavía está en pañales . Solo se puede esperar que el soporte del depurador mejore con el tiempo.
Actualmente, la mejor manera de depurar el código lambda es utilizar un depurador que admita establecer puntos de interrupción en el nivel del código fuente, es decir, especificando el nombre del archivo fuente y el número de línea.
fuente
Para agregar a la respuesta de @DocBrown, recuerde que actualmente las CPU son baratas pero la mano de obra es costosa.
En el costo general de un programa, el hardware generalmente es trivial en comparación con el costo de mantenimiento, que es, con mucho, la parte más costosa de un proyecto típico (incluso más que su desarrollo).
Por lo tanto, su código necesita optimizar el mantenimiento por encima de todo lo demás, excepto cuando el rendimiento es crítico (e incluso entonces el mantenimiento debe considerarse).
fuente