2009-02-18 25 views
15

duplicado exacto: Is there a performance difference between i++ and ++i in C++?
duplicado exacto: Difference between i++ and ++i in a loop?¿Qué es más eficiente i ++ o ++ i?


Lo que es más eficiente i ++ o ++ i?

Sólo he utilizado esto en Java y C/C++, pero estoy realmente pidiendo todos los idiomas que esto se implementa en.

En la universidad tuve un profesor nos muestran que ++ que era más eficiente, pero han pasado un par de años y me gustaría recibir comentarios de la comunidad SO.

+0

no estoy seguro de por qué esto ha sido downvoted así que – hmcclungiii

+1

porque se ha preguntado antes y nadie tenía ganas de encontrar la pregunta original – basszero

+0

Vota para tu cuenta como duplicado exacto. http://stackoverflow.com/questions/24901/ ... http://stackoverflow.com/questions/53455/ ... http://stackoverflow.com/questions/484462/ ... etc –

Respuesta

46

i ++:

  • crear una copia temporal de i
  • incremento i
  • vuelta la copia temporal

++ i:

  • incremento i
  • retorno i

con optimizaciones en adelante, es muy posible que el conjunto resultante es idéntica, sin embargo ++ i es más eficiente.

editar: tenga en cuenta que en C++, puedo ser cualquier objeto que admita el operador de prefijo y postfix ++. Para objetos complejos, el costo de copia temporal no es insignificante.

+0

En muchos procesadores, estas dos operaciones son una sola instrucción. –

+4

Depende de lo que sea "i". –

+0

Esta Q nos etiqueta con C++ y Java .. Me pregunto si Java es diferente. – izb

5

No importa en un compilador moderno.

int v = i++; 

es lo mismo que

int v = i; 
i = i + 1; 

Un compilador moderna descubrirá que v no se utiliza y el código para calcular v es (sin efectos secundarios) puros. A continuación, se eliminará v y el código de misiones y generará este

i = i + 1; 
+0

¿Por qué el voto a favor?Si no estás usando el efecto secundario, tiene razón, no hay diferencia. –

+0

Iba a hacer la misma pregunta. – kemiller2002

+0

No importa hoy quizás debido a hardware más barato y extremadamente rápido. Hace 10 años, sin embargo, esta pregunta era completamente válida. – Elroy

2

bien en C++ creo que tienen diferentes usos, dependiendo de cuando se desea que la variable actualizada. La eficiencia no debe determinar cuándo se usa uno sobre el otro, pero supongo que tendrían la misma eficiencia de cualquier manera.

+0

correcto, ++ Primero agregaré uno y luego usaré el valor, i ++ usará el valor y agregue uno después. –

0

A menos que me falta algo, deberían tener la misma eficacia. Ambos deberían dar como resultado una sola instrucción de agregar. Es solo una cuestión de dónde tiene lugar la instrucción add: al principio o al final de su línea de código.

3

sí importa! Sobre todo si se encuentra en C++ ...

++i // the prefered way, unless.. 
auto j = i++ // this is what you need 

Siempre debe usar la notación de prefijo para evitar la copia necesaria gastos generales y con C++ esto es importante!

36

Me gustaría buscar en otro lugar para el potencial de optimización.

0

++ i toma 1 menor de instrucciones del procesador de i ++ en ensamblador x86 sin optimización

+0

Me gustaría ver su razonamiento sobre eso. Cuando lo reduzco como una operación independiente, obtengo la misma cantidad de instrucciones del procesador. –

7

Eficiencia no debe ser su preocupación: es que significa. Los dos son no iguales, a menos que sean independientes: uno opera el pre-uso del valor, el otro mensaje.

int i; i = 1; cout < < i ++; // Devuelve 1

int i; i = 1; cout < < ++ i; // Devuelve 2

Cuando el significado no es importante, la mayoría de los compiladores traducirán tanto ++ i como i ++ (por ejemplo, en un bucle for) en el mismo código de máquina/máquina virtual.

0

No hay diferencia. Usa la construcción que tenga más sentido.

Si su aplicación se ejecuta lentamente, puedo garantizarle que nunca será debido a las diferencias de velocidad en la operación con incremento entero. Si es así, es un error grave en el compilador. Los problemas de la velocidad en su aplicación serán ineficiencias algorítmicas, esperando IO, y así sucesivamente.

No se preocupe por problemas que no tenga. La optimización prematura es la raíz de todo mal.

2

++ i es potencialmente más eficiente para una implementación no trivial del operador ++, pero incluso en ese escenario, el compilador puede optimizar el intermedio intermedio.

0

++ii++ es más rápido porque tiene que almacenar i, a continuación, se incrementará, a continuación, devolver el valor almacenado de i. ++i simplemente incrementa i y luego lo devuelve.

// ++i 
i += 1; 
return i; 

// i++ 
temp = i; 
i += 1; 
return temp; 
0

A stand-alone "i ++;" o "++ i" debería generar código igualmente eficiente.La diferencia viene si lo estás usando en una expresión, donde el "efecto secundario" entra en juego.

Dicho esto, hubo un tiempo, cuando "todo el mundo es un Vax", y los compiladores apestaban, que ++ se decía que era más eficiente que i ++, incluso en un "para (i = 0; i < N; ++ i) "configuración de tipo.

0

Esta pregunta StackOverflow tiene una gran respuesta: Is there a performance difference between i++ and ++i in C?

me gustaría añadir que se debe utilizar lo que se adapta mejor a sus necesidades. Excepto en las aplicaciones más críticas para el tiempo, no es importante. Desde una perspectiva académica también, es mejor escribir un código que exprese lo que necesita y optimice al fin.

0

En general, es más fácil escribir i ++, por lo tanto, es más eficiente en términos de tiempo de productividad.

En serio, si i es un tipo de datos nativo (como int, double, etc.) - no hay diferencia.

Y es la aplicación dependía si se trata de un tipo definido por el usuario, como

class Type 
{ 
    Type& operator ++(){} 
    const Type& operator ++(int i){} 
}; 

T i; 
0

No hay respuesta correcta o incorrecta

ya que depende de

1) cómo se implementó por el compilador

2) qué CPU el sistema se ejecuta en

3) Si I es byte o palabra doble que

2

++ i no necesito una variable temporal para almacenar cosas en pensar en ellos como esto:.

++ i

int preIncrement(int i) 
{ 
    i = i + 1; 
    return i; 
} 

i ++

int i = 5; // as an example 
int postIncrement(_i) 
{ 
    int temp = _i; 
    i = _i + 1; 
    return temp; 
} 

Ver? Postincrement requiere una variable temporal. Suponiendo que el compilador no lo solucione todo, lo cual es casi seguro.

Por supuesto, más importante es la lógica del programa; se corre el riesgo de encontrarse con The Sad Tragedy of Micro-Optimisation Theatre si usted se preocupa de esto demasiado ... :)

0

Se dependen del contexto, por ejemplo:

x = i++ 

En este caso, 'x' será igual a 'yo', y solo después de eso 'i' aumentará en uno.

x = ++i 

En este caso, 'i' habrá aumento por uno y luego el nuevo valor de 'x' será asignado a 'x'.

En el caso de un bucle 'for', hay poca diferencia aparente aparte del rendimiento (++ i es más rápido).

0

En general, es más eficiente usar ++ i que i ++. La razón simple de esto es que ++ i es completamente el mismo que

i + = 1;

que para x86 es una instrucción única (y probablemente la mayoría de las otras arquitecturas ampliamente utilizadas). i ++ es sin embargo igual a

tmp = i; i + = 1;

Esto se debe a que el valor anterior de 'i' es lo que i ++ evalúa. Y claramente eso requiere más trabajo que simplemente i + = 1;

Pero como se indicó anteriormente, esto prácticamente no tiene impacto con un compilador suficientemente inteligente, ya que optimiza las operaciones no utilizadas. Para muchos lenguajes interpretados (ejemplo: PHP), es probable que haya una ganancia mínima en la velocidad de ++ i; Pero este aumento es insignificante.

-1

Es difícil responder a esto precisamente ya que depende de la implementación del compilador/intérprete.

Pero, en general se puede decir más o menos extender i ++ con las siguientes instrucciones:

COPY i to tmp 
INCREMENT tmp 
SAVE tmp as i 

Mientras ++ i se extenderá a más o menos:

LOAD i 
INCREMENT i 

se puede simplemente decir que ++ Es más rápido que i ++ ya que las implementaciones de lenguaje son bastante inteligentes y pueden optimizar estas instrucciones cuando sabe que no tendrá acceso al valor temporal de i ++. Esto generalmente ocurre en, por ejemplo, un ciclo for. Entonces, en muchos casos, es lo mismo.

Si está intentando este tipo de micro-optimizaciones, le aconsejo que haga un perfil/medida antes de elegir una sobre otra.

0

Generalmente, en C++, postfix requerirá la construcción adicional del objeto incrementado, mientras que el prefijo se aplica directamente al objeto. (O al menos he leído)

Como no puedo dar fe de cómo lo maneja el compilador debido a mi limitado conocimiento sobre el tema, podría manejarse para que sea un punto discutible.

Cuestiones relacionadas