que es mas rapido

Si tenemos los siguientes 2 fragmentos de código en c ++ que hacen la misma tarea:

int a, b=somenumber; while(b > 0) { a = b % 3; b /= 3; } 

o

 int b=somenumber; while(b > 0) { int a=b%3; b /= 3; } 

No sé mucho sobre diseño de architecture de computadora / c ++, pero creo que el primer código es más rápido porque declara el entero a al principio y solo lo usa en el bucle while, y en el segundo código el entero a es siendo declarado cada vez que el ciclo while comienza de nuevo. ¿Puede alguien ayudarme con esto, estoy en lo correcto o qué y por qué?

La statement int es información para el comstackdor y no se traduce en una instrucción que deba codificarse. Así que no hay diferencia. Declarar el int dentro del bucle no se inclinará hacia abajo. ¿Por qué no intentar comstackr ambos por sí mismo y hacer que el comstackdor produzca un código de ensamblaje para que pueda verlo por sí mismo?

No debería haber diferencia, pero para ser más empírico (¿anal?), Probé esto con g ++, creando una función para cada uno de los fragmentos de código. Tanto con como sin optimizaciones, generó un código idéntico sin importar dónde esté la statement int a .

 #include  int variant_a(int b) { int a; while(b > 0) { a = b % 3; b /= 3; } return b; } int variant_b(int b) { while(b > 0) { int a = b % 3; b /= 3; } return b; } int main() { std::cout << variant_a(42) << std::endl; std::cout << variant_b(42) << std::endl; } 

Este es el bucle no optimizado:

 _Z9variant_ai: .LFB952: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: subl $24, %esp .LCFI2: jmp .L2 .L3: movl 8(%ebp), %eax movl %eax, -20(%ebp) movl $1431655766, -24(%ebp) movl -24(%ebp), %eax imull -20(%ebp) movl %edx, %ecx movl -20(%ebp), %eax sarl $31, %eax subl %eax, %ecx movl %ecx, %eax addl %eax, %eax addl %ecx, %eax movl -20(%ebp), %edx subl %eax, %edx movl %edx, %eax movl %eax, -4(%ebp) movl 8(%ebp), %eax movl %eax, -20(%ebp) movl $1431655766, -24(%ebp) movl -24(%ebp), %eax imull -20(%ebp) movl %edx, %ecx movl -20(%ebp), %eax sarl $31, %eax movl %ecx, %edx subl %eax, %edx movl %edx, %eax movl %eax, 8(%ebp) .L2: cmpl $0, 8(%ebp) jg .L3 movl 8(%ebp), %eax leave ret 

y el optimizado:

 _Z9variant_ai: .LFB968: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: pushl %ebx .LCFI2: movl 8(%ebp), %ebx testl %ebx, %ebx jle .L2 movl $1431655766, %ecx .p2align 4,,7 .p2align 3 .L5: movl %ebx, %eax imull %ecx movl %ebx, %eax sarl $31, %eax movl %edx, %ebx subl %eax, %ebx jne .L5 .L2: movl %ebx, %eax popl %ebx popl %ebp ret 

En serio, ¿realmente importa? Este es el tipo de micro-optimizaciones que debes tratar de evitar. Escriba el código que sea más legible, de modo que IMHO sea el segundo bucle. El comstackdor es lo suficientemente bueno para hacer la optimización para este tipo de cosas y lo dejaría para hacer eso.

No hay “más rápido” en el estándar de C ++, a excepción de las garantías de rendimiento en la biblioteca estándar. Es probable que un comstackdor optimizado simplemente elimine a , ya que no se utiliza. Alternativamente, podría asignar a toda la memoria la función necesaria para todas las variables locales a la vez, y entonces tampoco haría ninguna diferencia.

La única pregunta legítima sobre construcciones de lenguaje de bajo nivel como esta es si su implementación en particular las ejecuta más rápido o más lento, y la mejor manera de averiguarlo es cronometrarlo usted mismo. Encontrará que muchas de estas cosas simplemente no importan, y si examina el código generado, a menudo encontrará que los comstackdores hacen lo mismo con diferentes formas de escribir código.

Por lo general, buscar microoptimizaciones es una mala idea, pero si está intentando configurar un estilo general, puede valer la pena (por ejemplo, usar ++i lugar de i++ ). Sin embargo, si está configurando un estilo para cualquier otro propósito que no sea legible, debe tener buenas razones para hacerlo. En este caso, eso significa probar el rendimiento.

No, no puede ser “declarado” en el bucle, ya que se declara en tiempo de comstackción. Yo diría que son iguales, pero el segundo podría haber sido más rápido si el tipo de variable fuera algo más complicado, con constructor y destructor.

Teóricamente la primera opción podría ser más rápida. En la práctica, espero que a y b se coloquen en registros de tal manera que el ensamblaje generado salga idéntico (lo que puede verificarse en el binario comstackdo). Si está ejecutando el bucle suficientes veces que cree que puede haber una diferencia, la única forma de saber es medir. Si su generador de perfiles no puede diferenciarlo, codifíquelo de manera que el código sea el más claro para los futuros mantenedores.

En general (como ya se mencionó) estos tipos de optimizaciones no proporcionarán ningún tipo de mejora significativa en el rendimiento del progtwig. En su lugar, debe buscar optimizaciones algorítmicas y de diseño.

No creo que haya ninguna diferencia en la práctica. No hay asignaciones de memoria involucradas, porque la memoria para las variables automáticas se asigna o se reserva en el momento de la comstackción.

Teóricamente, creo que el segundo también podría ser más rápido: el comstackdor tiene más información sobre dónde y cómo se usan las variables (por ejemplo, puede que reutilice la misma variable para algo que no esté relacionado más adelante).

Puede comenzar a preocuparse por tales cosas cuando se trata de tipos que son caros de construir. Por ejemplo, debería declarar un std :: vector en el bucle interno, o debería declararlo antes del bucle y clear() al principio del cuerpo del bucle (reutilizando la memoria asignada).

El primero DEBE ser más rápido; Sin embargo, el comstackdor suele ser lo suficientemente inteligente como para optimizar esto, por lo que probablemente no importe.

Para la pureza, sin embargo, la respuesta es la primera.

EDITAR: Es más rápido porque requiere solo una asignación en lugar de N (N es el número de iteraciones que realizará el bucle while).