tiempo sumatoria software sistema sirve resueltos que programas programacion programa por para optimizar optimizador optimización optimizacion operativo notacion matematica mantenimiento inicio informatica induccion explicacion equipo ejercicios ejemplos divisible demostrar demostracion computo complejidad big analisis algoritmos algoritmica c micro-optimization optimization performance

c - sumatoria - que es un programa optimizador



¿Por qué n++ se ejecuta más rápido que n=n+1? (10)

¿Quién dice que sí? Tu compilador lo optimiza todo, realmente, convirtiéndolo en un punto discutible.

En lenguaje C, ¿Por qué n++ ejecuta más rápido que n=n+1 ?

(int n=...; n++;) (int n=...; n=n+1;)

Nuestro instructor hizo esa pregunta en la clase de hoy. (esto no es tarea)


Creo que es más una cuestión de hardware que de software ... Si mal no recuerdo, en las CPUs antiguas, n = n + 1 requiere dos ubicaciones de memoria, donde ++ n es simplemente un comando de microcontrolador ... Pero dudo esto se aplica a las arquitecturas modernas ...


El compilador optimizará n + 1 en la nada.

¿Te refieres a n = n + 1 ?

Si es así, se compilarán en un ensamblaje idéntico. (Suponiendo que las optimizaciones estén activadas y que sean declaraciones, no expresiones)


En GCC 4.4.3 para x86, con o sin optimizaciones, compilan exactamente el mismo código de ensamblado y, por lo tanto, tardan la misma cantidad de tiempo para ejecutarse. Como puede ver en el ensamblado, GCC simplemente convierte n++ en n=n+1 , luego lo optimiza en el agregado de una instrucción (en el -O2).

La sugerencia de su instructor de que n++ es más rápido solo se aplica a compiladores muy antiguos que no optimizan, que no fueron lo suficientemente inteligentes como para seleccionar las instrucciones de actualización in situ para n = n + 1 . Estos compiladores han quedado obsoletos en el mundo de las PC durante años, pero aún se pueden encontrar para plataformas embebidas propietarias raras.

Código C:

int n; void nplusplus() { n++; } void nplusone() { n = n + 1; }

Conjunto de salida (sin optimizaciones):

.file "test.c" .comm n,4,4 .text .globl nplusplus .type nplusplus, @function nplusplus: pushl %ebp movl %esp, %ebp movl n, %eax addl $1, %eax movl %eax, n popl %ebp ret .size nplusplus, .-nplusplus .globl nplusone .type nplusone, @function nplusone: pushl %ebp movl %esp, %ebp movl n, %eax addl $1, %eax movl %eax, n popl %ebp ret .size nplusone, .-nplusone .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits

Conjunto de salida (con optimizaciones de -O2):

.file "test.c" .text .p2align 4,,15 .globl nplusplus .type nplusplus, @function nplusplus: pushl %ebp movl %esp, %ebp addl $1, n popl %ebp ret .size nplusplus, .-nplusplus .p2align 4,,15 .globl nplusone .type nplusone, @function nplusone: pushl %ebp movl %esp, %ebp addl $1, n popl %ebp ret .size nplusone, .-nplusone .comm n,4,4 .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" .section .note.GNU-stack,"",@progbits


En lenguaje C, el efecto secundario de las expresiones n++ es, por definición, equivalente al efecto secundario de la expresión n = n + 1 . Dado que su código solo se basa en los efectos secundarios, es inmediatamente obvio que la respuesta correcta es que estas expresiones siempre tienen un rendimiento exactamente equivalente. (Independientemente de cualquier configuración de optimización en el compilador, por cierto, ya que el problema no tiene absolutamente nada que ver con las optimizaciones).

Cualquier divergencia práctica en el rendimiento de estas expresiones solo es posible si el compilador intenta intencionalmente (y maliciosamente) introducir esa divergencia. Pero en este caso puede ir de cualquier manera, por supuesto, es decir, de cualquier forma que el autor del compilador quiera sesgarlo.


En realidad, la razón es que el operador se define de manera diferente para la corrección posterior que para la corrección previa. ++n aumentará "n" y devolverá una referencia a "n", mientras que n++ incrementará "n" devolverá una copia const de "n". Por lo tanto, la frase n = n + 1 será más eficiente. Pero tengo que estar de acuerdo con los carteles anteriores. Los buenos compiladores deberían optimizar un objeto de devolución no utilizado.


Eso sería cierto si está trabajando en un compilador de "edad de piedra" ...

En caso de "edad de piedra" :
++n es más rápido que n++ es más rápido que n=n+1
La máquina generalmente tiene increment x así como también add const to x

  • En el caso de n++ , tendrá solo 2 accesos a la memoria (leer n, inc n, escribir n)
  • En caso de n=n+1 , tendrá 3 accesos a memoria (leer n, leer const, agregar n y const, escribir n)

Pero el compilador de hoy convertirá automáticamente n=n+1 a ++n , ¡y hará más de lo que puedas imaginar!

También en los procesadores fuera de orden de hoy, a pesar del caso del compilador de "edad de piedra", ¡el tiempo de ejecución puede no verse afectado en absoluto en muchos casos!

Related


Los compiladores modernos deberían poder reconocer ambas formas como equivalentes y convertirlas al formato que mejor funcione en su plataforma de destino. Hay una excepción a esta regla: accesos variables que tienen efectos secundarios. Por ejemplo, si n es un registro de hardware mapeado en memoria, leerlo y escribirlo puede hacer algo más que simplemente transferir un valor de datos (por ejemplo, la lectura podría borrar una interrupción). Utilizaría la palabra clave volatile para que el compilador sepa que debe tener cuidado con la optimización de accesos a n , y en ese caso el compilador podría generar código diferente de n++ (operación incremental) y n = n + 1 (leer, agregar, y operaciones de la tienda). Sin embargo, para las variables normales, el compilador debe optimizar ambos formularios para la misma cosa.


Realmente no. El compilador realizará cambios específicos a la arquitectura de destino. Las micro-optimizaciones como esta a menudo tienen beneficios dudosos, pero lo más importante, ciertamente no valen la pena el tiempo del programador.


Todo eso depende de las directivas de compilación / procesador / compilación. Por lo tanto, hacer suposiciones "lo que es más rápido en general" no es una buena idea.