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);
}


Nessun commento:

Posta un commento