domingo, enero 18, 2009

Curiosidades en los compiladores de GNU

Haciendo unos programitas de ejemplos, escritos en lenguaje C++, como son muy pequeños y son compilados con el compilador de GNU, g++ en un sistema GNU/Linux, pensé que el binario iba a resultar tan pequeño, dado el tamaño del código fuente, que con respecto el mismo programa escrito en C, no iba a haber mucha diferencia en el tamaño.

Sin embargo la diferencia entre uno y otro si es notable, por ejemplo para el caso particular del siguiente código en C++:


using namespace std;
#include <iostream>

// Funcion que es llamada
int llamada(int x, int y){
cout << "Estamos en la funcion!!" << endl;
return(x+y);
}

int main(void){
//Estos comentarios son propios de C++
cout << "Vamos a llamar a la funcion..." << endl;

// Llamamos a la funcion
// y asignamos
int z=llamada(5,7);
cout << "Resultado: "<< z << endl;

// Llamamos desde la salida estandar
cout << "Resultado desde la llamada: " << llamada(6,7) << endl;
cout << "Programa terminado\n" << endl;

return 0;
}

Y el mismo programa en C:

#include <stdio.h>

// Funcion que es llamada
int llamada(int x, int y){
printf("Estamos en la funcion!!i\n");
return(x+y);
}

int main(void){
//Estos comentarios son propios de C/C++
printf("Vamos a llamar a la funcion...\n");

// Llamamos a la funcion
// y asignamos
int z=llamada(5,7);
printf("Resultado: %d\n", z);

// Llamamos desde la salida estandar
printf("Resultado desde la llamada: %d \n", llamada(6,7));
printf("Programa terminado\n");

return 0;
}


Que como se observa, no hay mayor diferencia en las declaraciones y en el propósito del programa, y sin embargo al compilarlo el primero genera un ejecutable de tamaño de 9372 bytes, mientras que el segundo su tamaño es de 6718 bytes, lo que me lleva a pensar que en una aplicación realmente grande, ese tamaño seguramente se ha de incrementar bastante.

La compilación fue el primero con g++ sin más argumentos, el segundo fue con gcc sin argumentos, el ejemplo es de un documento llamado: Tutorial de C++ (o el diario de Peter Class)

ACTUALIZACIÓN:

Después de leer el comentario, debo aclarar que solo es una suposición, y que en donde dice:"... lo que me lleva a pensar que en una aplicación realmente grande, ese tamaño seguramente se ha de incrementar bastante..."
Una mejor forma de explicar mi idea es:"... lo que me lleva a pensar que en una aplicación realmente grande, una proporción equivalente pudiera mantenerse, siendo el binario de la versión en c++, de mayor tamaño..."

4 Comentarios:

Anonymous Anónimo dijo...

Desafortunadamente la observaci'on es correcta pero la conclusi'on no lo es.

Le recomiendo que revise la documentaci'on del formato elf y a.out, as'i como un peque~no cursillo en compiladores para que encuentre el motivo de la observaci'on que acaba de exponer.

Intente correr el programa objcopy --strip o strip sobre los binarios y ver que resulta, tambien probar con los flags que habilitan los simbolos de debug y el gnu profiler.

Adios, y suerte

6:45 a.m.  
Blogger César dijo...

Saludos

No estoy concluyendo nada, solo estoy haciendo una suposición. (Lo cual no parece que haya expresado adecuadamente).

No tengo otros compiladores (como los de intel), para verificar si sucede algo semejante.

Por otro lado, ambos binarios son del tipo elf (no me queda claro a que viene lo de la referencia al formato a.out).

Ahora bien, es claro que un lenguaje es estructurado, mientras que otro es orientado a objetos, y cada uno tiene un tratamiento diferente sobre el código fuente en el que trabajan.

Sin embargo, yo esperaba que al venir del mismo grupo de trabajo, el compilador de c++, generase un binario al menos muy cercano al de c, dado que en ambos casos, el ejemplo es estructurado.

Por otro lado, gracias por la referencia a los comandos strip y objcopy, y solo comentar que al correrlo sobre mis binarios, el resultado fue equivalente, el de c++ siguen siendo mayor que el de c (5156 de c++ y 3280 de c en bytes).

12:35 p.m.  
Blogger Alejandro Valenzuela dijo...

No le encuentro sentido al comentario de valkertown, quizás si se bajara de su pedestal podríamos entender más sobre su punto de vista.

1:16 p.m.  
Anonymous valkertown dijo...

Gracias a duckduck go volvi por aquí.

@cesar En principio c++ era un preprocesador de c, hoy en día es un lenguaje con un compilador propio con multiples optimizaciones.

El problema fundamental de la afirmación, suposición (o ¿pregunta?) es que desconoce totalmente el hecho que son dos lenguajes distintos y generaliza una observación sin suficientes mediciones.



Nuevamente la recomendación de usar objdump viene al caso, revise el código relevante eliminado el overhead del formato elf, si genera a.out el overhead debe ser distinto y luego revise el overhead que genera la inicialización y otros campos fijos que incluyen cada uno de estos lenguajes. Luego de esto puede realizar una medición comparable del resultado de la compilación de su código en especifico.

@alejandro Las referencias son correctas, y la información que di es apropiada. Si no le gusta el estilo no es mi problema.

3:51 p.m.  

Publicar un comentario

Suscribirse a Comentarios de la entrada [Atom]

<< Página Principal