Mientras que otros tienen razón en que la división es una operación muy lenta (ya que esencialmente el algoritmo de división es casi el mismo que usted conoce de la escuela y no se “paraleliza” bien) también están equivocados porque en este caso particular no hay división involucrada . Los compiladores son lo suficientemente inteligentes como para reemplazar la división (y el módulo) con la multiplicación siempre que el segundo operando sea una constante. Probablemente podría llegar a esta optimización recordando que la división por x es casi lo mismo que la multiplicación por 1 / x. Por supuesto, en realidad no podemos usar números reales, solo sus aproximaciones binarias finitas, por lo que solo debe tomar los 32 bits más significativos de 1 / x y codificarlos en tiempo de compilación, como por ejemplo, y. Luego, en lugar de x / n, puede usar n • y >> 32, que es una buena aproximación, pero a menudo requiere una verificación adicional para el error de redondeo; por ejemplo, puede comparar n-result • x <x, pero los compiladores conocen mejores trucos que eso . En mi opinión, sin mirar el código de ensamblaje generado por su compilador, es imposible saber qué se hace realmente en cada una de estas implementaciones.
La pregunta sobre la velocidad también es algo que uno no puede resolver sin probar en el mundo moderno y cuanto antes se dé cuenta de esto, será mejor programador, ya que hay más problemas causados por el culto de la carga y el juicio erróneo que por el código subóptimo.
Mi intuición es que dos ramas condicionales pueden disparar la predicción anticipada del procesador y ralentizar la canalización, pero no estoy seguro de si es probable en su escenario realizar dos saltos y cómo el compilador organizará las rutas predeterminadas para estas dos condiciones .
Pruébalo:)
Dicho todo esto, considere este programa:
int main(int argc,char * args[]){
if(argc/10){
return 1;
}else{
return 0;
}
}
y compilar mira el ensamblaje:
- Cómo demostrar que cada serie absolutamente convergente es convergente si [math] X [/ math] es un espacio normado dimensional finito
- ¿Qué es el inverso multiplicativo modular?
- Cómo demostrar que la ecuación de Diofantina [matemática] x ^ 4-2y ^ 2 = 1 [/ matemática] solo tiene las soluciones triviales, a saber (1,0) y (-1,0)
- ¿Hay alguna diferencia entre ‘N veces más grande que’ y ‘N veces más grande que’?
- ¿Cuál es la prueba para gcd (a1, a2, …, ak) = gcd (gcd (a1, a2), a3, …, ak)?
g ++ –save-temps test.cpp
prueba de gato.
.archivo “test.cpp”
.texto
.globl principal
.type main, @function
principal:
.LFB0:
.cfi_startproc
pushl% ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl% esp,% ebp
.cfi_def_cfa_register 5
movl 8 (% ebp),% eax
addl $ 9,% eax
cmpl $ 18,% eax
jbe .L2
movl $ 1,% eax
jmp .L3
.L2:
movl $ 0,% eax
.L3:
popl% ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
jubilado
.cfi_endproc
.LFE0:
.size main,.-main
.ident “GCC: (Debian 4.7.2-5) 4.7.2″
.section .note.GNU-stack, “”, @ progbits
Observe que no hay operación de división en este ensamblado (por lo que otros están equivocados).
Tenga en cuenta que no hay multiplicación (así que me equivoqué).
Tenga en cuenta que el ensamblaje es algo totalmente diferente al código cpp.
Y esta, mi amigo, es la lección más importante que puedes obtener aquí: aprender a ser abierto, aprender a no confiar en tus sentimientos, aprender a profundizar y verificar los hechos 🙂
Por cierto, ¿qué hace el compilador en este caso? Parece que reemplazó n / 10 con n <= 9.