sabato 20 ottobre 2012

Quale compilatore C produce il codice più "veloce"? The winner is ...

Nel  precedente post ci eravamo chiesti quale compilatore C gratuito per Windows producesse il codice più veloce e abbiamo stabilito il nostro protocollo di test. Oggi vediamo i risultati. Per misurare il tempo di esecuzione del codice compilato abbiamo usato il comando unix Time reso disponibile da CygWin. Lo script usato è il seguente:




And, the winner is ...

Dev-C++. Congratulazioni!

I risultati della prova sono riportati nella figura qui a destra. Dev-cpp è quello che produce codice più veloce. La versione di Dev-Cpp installata usa gcc MingW versione 4.6.2 mentre la versione di gcc Mingw testata è la 4.6.1 (ultima stabile sul sito ufficiale Mingw).
Tutti i compilatori testati sono stati invocati senza nessuna opzione di ottimizzazione del codice.

sabato 13 ottobre 2012

Quale compilatore C gratuito per windows produce il codice più veloce? (parte 1)

E poi, a che cosa potrebbe mai servire saperlo? Beh, intanto la curiosità è umana :). Poi, ci sono casi in cui si ha bisogno di produrre codici veloci per applicazioni realtime o per applicazioni batch su grandi moli di dati. Quest'ultima circostanza potrebbe sembrare alquanto fumosa per chi non ha mai visto programmi che macinano grosse moli di dati per produrre, ad esempio, stampe quali quelli usati per
stampare le bollette delle utenze o le famigerate cartelle esattoriali. Detto in altro modo, ridurre il tempo di elaborazione della singola unità di informazione trattata di qualche punto percentuale fa la
differenza quando si elaborano milioni di tali unità di informazione. Chi invece ha esperienza di real time o big batch sa di che cosa stiamo parlando. L'idea l'ho avuta alcuni giorni fa quando ho lettoquesto interessante post di juhan sul blog OK, panico circa il confronto sulla velocità di esecuzione di un prefissato algoritmo "macina numeri" in diversi linguaggi di programmazione. Io ho pensato di mettere alla prova 5 compilatori C/C++ per windows disponibili gratuitamente.
I compilatori che useremo sono quelli in uso su c-lessons-online.org. Il codice usato è quello del post che mi ha ispirato con qualche piccolissima modifica lo riporto qui di seguito:
Nel prossimo post compileremo a parità di opzioni standard il codice con i 5 compilatori individuati e commenteremo i risultati insieme.

#include <stdio.h>
#include <math.h>
static double f[14];static double fsin(double a) {
   
return a - pow(a, 3.0) / f[3] + pow(a, 5.0) / f[5]
            - pow(a, 7.0) / f[7] + pow(a, 9.0) / f[9]
            - pow(a, 11.0) / f[11] + pow(a, 13.0) / f[13];
}
static double fcos(double a) {
   
return 1.0 - pow(a, 2.0) / f[2] + pow(a, 4.0) / f[4]
              - pow(a, 6.0) / f[6] + pow(a, 8.0) / f[8]
              - pow(a, 10.0) / f[10] + pow(a, 12.0) / f[12];
}
static double myln(double x) {
   
if (x == 0.0) {
       
return -1.0e20;
   }
else {
       
double r = (x - 1.0) / (x + 1.0);
       
return 2.0 * (r + pow(r, 3.0) / 3.0
           + pow(r, 5.0) / 5.0
           + pow(r, 7.0) / 7.0
           + pow(r, 9.0) / 9.0);
   }
}
static double ln10 = 2.2548000538926538; //
static double mylog(double x) {
   
return x / ln10;
}
int main(int argc, char **argv) {
   
int i, j;
   f[0] = 1.0;
   
for (i = 1; i < 14; i++)
       f[i] = i * f[i - 1];

   ln10 = myln(10.0);
   
int deg = 60 * 60;
   
int nsteps = 180 * deg;
   
double step = M_PI / nsteps;
   
double ssum;
   
double csum;
   
double a, s, c, t = 0.0;
   
double ls, lc;

   
for (j = 1; j < 11; j++) {
       ssum = 0.0;
       csum = 0.0;
       
for (i = 0; i <= nsteps; i++) {
           a = i * step;
           s = fsin(a);
           ls = mylog(myln(s));
           ssum += s;
           c = fcos(a);
           lc = mylog(myln(c));
           csum += c;

           
if ((i % (10 * deg)) == 0) {
               
if (c != 0.0)
                   t = s / c;

               printf(
"%3d %11.8f %11.8f %11.8f %15.8e\n",
                      (i / deg), a, s, c, t);
               printf(
" %15.8e %15.8e\n", ls, lc);
           }
       }
   }
   printf(
"%15.8e\n", ssum);
   printf(
"%15.8e\n", csum);
}