Y me ha surgido una duda, la cual es; ¿Cómo aligerar los programas para mejorar los tiempos de ejecución?
Tras hacer varias pruebas con un procedimiento "Hi World", he conseguido mejorar los tiempos notablemente.
El programa con el que vamos a empezar a probar, es bastante simple. Basta con compilar y analizar, aquí el código fuente:
Podemos analizar con gdb el comportamiento de nuestro programa:
#include <stdio.h>
int main(void)
{
printf("Hola Mundo\n");
return 0;
}
(gdb) disas mainEn negrita, la llamada a la función puts, la cual se encarga de imprimir el mensaje en pantalla.
Dump of assembler code for function main:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: and $0xfffffff0,%esp
0x080483ea <+6>: sub $0x10,%esp
0x080483ed <+9>: movl $0x80484c0,(%esp)
0x080483f4 <+16>: call 0x8048318
0x080483f9 <+21>: mov $0x0,%eax
0x080483fe <+26>: leave
0x080483ff <+27>: ret
End of assembler dump.
Ahora analicemos el tiempo de ejecución, con el comando time:
serch@serch-server:~/Escritorio$ time hw
hw: orden no encontrada
real 0m0.289s
user 0m0.200s
sys 0m0.080s
Como vemos es bastante ligero. Pero ahora, en vez de usar stdio y printf, vamos a comprobar el comportamiento con fprintf. Sustituimos printf por la función ya comentada y...
serch@serch-server:~/Escritorio$ time hwComo vemos, hemos aligerado "real" y "sys" (Aunque no mucha cantidad).
hw: orden no encontrada
real 0m0.286s
user 0m0.224s
sys 0m0.060s
Veamos el disas de la modificación de nuestro programa:
(gdb) disas mainComo vemos, hacemos muchos mas ciclos que con printf, aunque consumimos menos recursos. Tal y como observamos en negrita, ahora llamamos a fwrite. Para aligerar mas el programa, podríamos llamar directamente a write (En sistemas GNU/Linux, con la cabecera unistd).
Dump of assembler code for function main:
0x08048414 <+0>: push %ebp
0x08048415 <+1>: mov %esp,%ebp
0x08048417 <+3>: and $0xfffffff0,%esp
0x0804841a <+6>: sub $0x10,%esp
0x0804841d <+9>: mov 0x804a020,%eax
0x08048422 <+14>: mov %eax,%edx
0x08048424 <+16>: mov $0x8048510,%eax
0x08048429 <+21>: mov %edx,0xc(%esp)
0x0804842d <+25>: movl $0xb,0x8(%esp)
0x08048435 <+33>: movl $0x1,0x4(%esp)
0x0804843d <+41>: mov %eax,(%esp)
0x08048440 <+44>: call 0x8048344
0x08048445 <+49>: mov $0x0,%eax
0x0804844a <+54>: leave
0x0804844b <+55>: ret
End of assembler dump.
Tras pasarnos al write, el código de nuestro programa queda así:
Veamos el disas de este código:
#include <stdio.h>
int main(void)
{
write(1, "Hola Mundo\n", 50);
return 0;
}
(gdb) disas main
Dump of assembler code for function main:
0x080483e4 <+0>: push %ebp
0x080483e5 <+1>: mov %esp,%ebp
0x080483e7 <+3>: and $0xfffffff0,%esp
0x080483ea <+6>: sub $0x10,%esp
0x080483ed <+9>: movl $0x32,0x8(%esp)
0x080483f5 <+17>: movl $0x80484d0,0x4(%esp)
0x080483fd <+25>: movl $0x1,(%esp)
0x08048404 <+32>: call 0x804830c
0x08048409 <+37>: mov $0x0,%eax
0x0804840e <+42>: leave
0x0804840f <+43>: ret
End of assembler dump.
Como vemos, ahora hacemos menos ciclos que antes. Veamos de nuevo el tiempo de ejecución:
serch@serch-server:~/Escritorio$ time hw¡¡No ha mejorado gran cosa!! Pero esto tiene explicación: Los que tengan la vista atenta, se habrán dado cuenta: He puesto el buffer de write a 50. Probemos con el buffer ajustado a la cadena de texto, osea, exactamente a 10.
hw: orden no encontrada
real 0m0.302s
user 0m0.224s
sys 0m0.060s
serch@serch-server:~/Escritorio$ time hwY ya hemos optimizado algo el tiempo de ejecución real.
hw: orden no encontrada
real 0m0.289s
user 0m0.212s
sys 0m0.080s
Esto se nota poco en programas pequeños como este, pero a la hora de usar estas funciones en programas mas "grandes y serios", la cosa cambia, y mucho. Sin ir mas lejos, llamando directamente a write en una función, me he ahorrado mas de 300s, usando fprintf.
Esto es lo bonito de la programación: hagas como hagas un programa, siempre puedes revisarlo un poco por pequeño que sea ^^
ResponderEliminarBueno, y esto es un hi world, cuando haces programas mas grandes, detalles como estos, aparte de evitarte muchos problemas, te restan un tiempo de ejecución enorme xD
ResponderEliminarwrite .. me recuerda a fortran por la forma de usarse....
ResponderEliminar