2010-02-02 17 views
5

Hay Dear!If instrucción en C++

Sé que si la declaración es una declaración caro en C++. Recuerdo que una vez mi maestro dijo que si el enunciado es una declaración costosa en el sentido del tiempo de la computadora.

Ahora podemos hacer cualquier cosa mediante el uso de la instrucción if en C++, por lo que esta es una declaración muy poderosa en la perspectiva de programación, pero es costosa en la perspectiva de tiempo de la computadora.

soy un principiante y estoy estudiando curso de estructura de datos después de la introducción al curso de C++. mi pregunta es
¿Es mejor para mí usar if statement extensivly?

+1

¿Estás diciendo usar una instrucción if en lugar de una declaración if? ¿Qué estás sugiriendo usar en su lugar? –

+1

if statement es más expansivo que + - * /, ¡pero es mucho más económico que loop! así que úsalas cuando las necesites :) – Tommy

+0

¿Cómo puede 'si' ser costoso su prueba seguida de un salto en caso de que solo bloquee más? Es por eso que siempre pone el código justo después si la prueba es verdadera la mayor parte del tiempo. Una multiplicación es más costosa. Entonces, ¿quién te dijo que 'si' es una afirmación cara, que probablemente sea más fácil de mantener que de velocidad? – affan

Respuesta

13

no estoy seguro de cómo se puede generalizar que la sentencia if es caro.

Si tiene

if (true) { ... } 

entonces este será el if más likele optimizarse llevar por su compilador.

Si, por el contrario, tiene ..

if (veryConvolutedMethodTogGetAnswer()) { .. } 

y el método veryConvolutedMethodTogGetAnswer() hace un montón de trabajo, entonces, se podría argumentar tha este es un caro si declaración, pero no por el caso, pero debido al trabajo que estás haciendo en el proceso de toma de decisiones.

"si" 's en sí mismos no son por lo general 'costosa' en términos de ciclos de reloj.

5

Yo diría que una gran cantidad deif statement es costoso desde la perspectiva de la mantenibilidad.

1

se debe escribir el código sea correcto, fácil de entender y fácil de mantener. Si eso significa usar declaraciones if, ¡utilícelas! Me cuesta creer que alguien te haya sugerido que no uses la declaración if.

Tal vez su instructor entiende que se debe evitar algo como esto:

if (i == 0) { 
    ... 
} else if (i == 1) { 
    ... 
} else if (i == 2) { 
    ... 
} ... 

En ese caso, podría ser más lógico reconsiderar su estructura y/o algoritmo de datos, o por lo menos, utilizar switch/case :

switch (i) { 
    case 1: ...; break; 
    case 2: ...; break; 
    ...; 
    default: ...; break; 
} 

Pero incluso entonces, lo anterior es mejor más debido a la legibilidad mejorada en lugar de la eficiencia. Si realmente necesita eficiencia, cosas como la eliminación de if son probablemente una mala forma de comenzar. En su lugar, debe perfilar su código y descubrir dónde está el cuello de botella.

Respuesta corta: ¡use if si y solo si tiene sentido!

0

En términos de tiempo de la computadora, el enunciado "si" en sí mismo es una de las declaraciones más baratas que existen.

Simplemente no ponga veinte de ellos en una fila cuando hay una mejor manera de cambiar o una tabla hash, y lo hará bien.

+0

Encuentro esto dudoso. Hay/un costo para una rama condicional, y excede (por ejemplo) la aritmética de enteros básicos. –

+0

Sí, la aritmética de enteros básicos es más rápida a 0.2ns para un procesador típico hoy en día, pero "si" es casi tan rápido, típicamente 0.5ns en promedio, y la mayoría de las operaciones, como las llamadas a métodos, alcanzan los cientos de nanosegundos. Respaldo mi afirmación de que "si" es ** una de ** las declaraciones más baratas que hay. – RobC

17

Si las declaraciones se compilan en un conditional branch. Esto significa que el procesador debe saltar (o no) a otra línea de código, dependiendo de una condición. En un procesador simple, esto puede causar un pipeline stall, que en términos simples significa que el procesador tiene que tirar el trabajo que hizo temprano, lo que desperdicia tiempo en la línea de montaje. Sin embargo, los procesadores modernos usan branch prediction para evitar puestos, por lo que las declaraciones se vuelven menos costosas.

En resumen, sí, pueden ser caros. No, generalmente no deberías preocuparte por eso. Pero Mykola trae un punto separado (aunque igualmente válido). Polymorphic code a menudo es preferible (para facilidad de mantenimiento) a las declaraciones if o case

+0

Totalmente de acuerdo. Rocas de polimorfismo :) – ScaryAardvark

+0

Matthew solo para aclarar si el salto se realiza muy cerca de la instrucción de ejecución actual, que también se espera que esté presente en la memoria caché. Eso hará si todavía es caro. La mayoría de ellos salta a pocas instrucciones de distancia.Y en segundo lugar, una llamada a función puede dar como resultado más pérdida de tiempo que una instrucción if, ya que una llamada a una función requiere guardar el parámetro para pasar la pila y que saltar a otra ubicación puede estar muy lejos. – affan

+0

Si está saltando a una línea cercana, puede estar en caché de instrucciones. Pero si el procesador predice mal, todavía podría haber una parada en la tubería. Y la lógica de predicción de bifurcación es parte del costo real. Una llamada de función también es costosa. –

0

Puede usar Switch en lugar que hace que sea más legible, pero no si es más rápido. Si tiene algo como:

if (condition1) { 
    // do something 
} else if (condition2) { 
    // do something 
} else if (condition3) { 
    // do something 
} else if (condition4) { 
    // do something 
} 

No soy lo que se puede hacer para acelerarlo. si condition4 se produce con más frecuencia, puede moverlo a la parte superior.

7

La optimización prematura es una mala idea. Usa declaraciones if donde tengan sentido. Cuando descubra una parte de su código donde su desempeño necesita mejoras, entonces posiblemente trabaje en eliminar declaraciones de esa parte de su código.

Si las declaraciones pueden ser costosas porque obligan al compilador a generar instrucciones de bifurcación. Si puede encontrar una manera de codificar la misma lógica de tal manera que el compilador no tenga que bifurcar en absoluto, el código será mucho más rápido, incluso si hay más instrucciones totales. Recuerdo haberme sorprendido increíblemente de cómo recodificar un pequeño fragmento de código para usar varias manipulaciones de bit en lugar de hacer cualquier ramificación lo aceleró en un factor de 10-20%.

Pero esa no es una razón para evitarlos en general. Es algo a tener en cuenta cuando intenta extraer la última parte de la velocidad de una sección de código que sabe que es crítica para el rendimiento porque ya ha ejecutado un generador de perfiles y varias otras herramientas para demostrarlo.

Otra razón por la cual las declaraciones pueden ser costosas es porque pueden aumentar la complejidad de su programa, lo que hace que sea más difícil de leer y mantener. Mantenga baja la complejidad de sus funciones individuales. No use demasiadas declaraciones que creen diferentes rutas de control a través de su función.

+0

+1 por mencionar que la optimización prematura es una mala idea – chrmue

2

Una instrucción if implica una bifurcación condicional que puede ser un poco más cara que un código que no se bifurca.

Como ejemplo, contando el número de veces una condición es verdadera (por ejemplo, la cantidad de números en un vector son mayores que 10000):

for (std::vector<int>::const_iterator it = v.begin(), end = v.end(); it != end; ++it) { 
    //if (*it > 10000) ++count; 
    count += *it > 10000; 
} 

La versión que simplemente añade 1 o 0 a la de mayo total acumulado ser un poco más rápido (lo intenté con 100 millones de números antes de poder discernir la diferencia).

Sin embargo, con MinGW 3.4.5, utilizando un algoritmo estándar dedicada resulta ser notablemente más rápido:

count = std::count_if(v.begin(), v.end(), std::bind2nd(std::greater<int>(), 10000)); 

Así que la lección es que antes de comenzar a optimizar prematuramente, el uso de algunos trucos que he aprendió de los internets, puede probar las prácticas recomendadas para el idioma. (Y, naturalmente, primero asegúrese de que esa parte del programa sea irrazonablemente lenta en primer lugar.)

Otro lugar donde a menudo puede evitar la evaluación de condiciones complicadas es usando tablas de búsqueda (una regla de oro: los algoritmos a menudo pueden hacerse más rápidos si les permite usar más memoria). Por ejemplo, las vocales de conteo (aeiou) en una lista de palabras, donde se puede evitar la ramificación y la evaluación de múltiples condiciones:

unsigned char letters[256] = {0}; 
letters['a'] = letters['e'] = letters['i'] = letters['o'] = letters['u'] = 1; 

for (std::vector<std::string>::const_iterator it = words.begin(), end = words.end(); it != end; ++it) { 
    for (std::string::const_iterator w_it = it->begin(), w_end = it->end(); w_it != w_end; ++w_it) { 
     unsigned char c = *w_it; 
     /*if (c == 'e' || c == 'a' || c == 'i' || c == 'o' || c == 'u') { 
      ++count; 
     }*/ 
     count += letters[c]; 
    } 
} 
0

En un estructuras de datos supuesto, el rendimiento de un comunicado if no importa. La pequeña diferencia entre una declaración if y cualquiera de las alternativas oscuras está totalmente inundada por la diferencia entre las estructuras de datos. Por ejemplo, en el siguiente pseudocódigo

FOR EACH i IN container 
    IF i < 100 
    i = 100 
    container.NEXT(i) 
END FOR 

el rendimiento es más determinada por container.NEXT(i); esto es mucho más costoso para las listas vinculadas que para las matrices contiguas. Para las listas enlazadas, esto requiere un acceso extra a la memoria, que dependiendo de la caché (s) puede tomar entre 2.5 ns y 250 ns. El costo de la declaración if se mediría en fracciones de un nanosegundo.

0

Me enfrenté con problemas de rendimiento debido a muchas sentencias if llamadas bucles dentro de scripts por lotes, así que en su lugar utilicé matemáticas enteras para emular la instrucción if, y mejoró dramáticamente el rendimiento.

if [%var1%] gtr [1543] 
     set var=1 
    else 
     set var=0 

equivalente a

set /a var=%var1%/1543 

Incluso he utilizado expresiones mucho más largas, con muchas operaciones y /%, y todavía estaba preferible a una sentencia if.

Sé que esto no es C++, pero supongo que es el mismo principio. Por lo tanto, siempre que necesite rendimiento, evite las declaraciones condicionales tanto como pueda.

Cuestiones relacionadas