Entra

View Full Version : Benchmark performance vari linguaggi


Vash1986
15-09-2006, 17:53
Ho da mesi e mesi una sfrenata curiosità di sapere le differenze prestazionali tra i vari linguaggi.

Ogni giorno mi tempesto di domande: ma il C ha qualche vantaggio prestazionale sul C++? Ma il C# è lento come il Java oppure non è veramente semi-interpretato? Ma è davvero grande la diff tra C++ e C#? Ma Delphi e Free Pascal sono potenti come il C? Ma sarà vero che il fortran in applicazioni di puro calcolo inchiappetta il C?

E' tempo che queste domande abbiano una risposta concreta :D

Perciò volevo creare un programmino Benchmark con ognuno di questi linguaggi (personalmente conosco C/Cpp, C# e Java, e un pochino di Pascal).

Ovviamente un programma di puro calcolo sarebbe molto limitativo e non dimostrerebbe niente. Quindi volevo fare un programma console che ti chiede di scegliere tra vari test, e poi ti dice quanti secondi ha impiegato.

Ho pensato subito a questi primi test

1- Calcolare la milionesima cifra decimale di pi greco con la formula di Bailey.

2- Ricorsione: trovare tutte le uscite da un enorme labirinto disegnato con un editor di testo, e calcolare qual è la più breve a partire da un punto del labirinto. Chiaramente sarà un algoritmo esponenziale n^4.

3- Manipolazione stringhe (accetto suggerimenti su cosa farci... concatenarle? renderle tutte maiuscole o tutte minuscole?)

4- Gestione array: verrà creato un enorme array bidimensionale e riempito con random short. Poi verrà ordinato secondo un determinato criterio. Poi invertito. Poi duplicato.

Dunque vi chiedo consiglio: quali altri test potrebbero fornire risultati significativi per misurare le performance del linguaggio? Chessò, un test che metta a confronto l'utilizzo degli oggetti in C++ con le struct in C. Ad esempio tempo fa un tizio mi disse che se tenti di imitare "manualmente" in C l'ereditarietà e il polimorfismo, e il funzionamento degli oggetti, alla fine rischi di ottenere performance peggiori che utilizzando C++ con oggetti veri e propri.

Ma magari anche un test che metta a confronto la velocità di creazione e utilizzo degli oggetti (e consumo ram) di C++ e C# e Java magari.

Importante: questo benchmark serve a valutare le prestazioni in termini assoluti, non il rapporto tra fatica del programmatore e prestazioni.

ally
15-09-2006, 20:00
...penso che piu' il linguaggio sarà a basso livello e piu' il programmatore sarà cazzuto piu' le performance aumenteranno...il problema è che il numerino che deriverà da tale bench sarà solo fine a se stesso...

...ciao...

Vash1986
15-09-2006, 21:00
Uhm... sorge un problema.

Sorgente:


#include <stdio.h>
#include <math.h>
#include <time.h>

main()
{
clock_t time = clock();
double pid, s1, s2, s3, s4;
double series (int m, int n);
void ihex (double x, int m, char c[]);
int id = 1000000;
#define NHX 16
char chx[NHX];

/* id is the digit position. Digits generated follow immediately after id. */

s1 = series (1, id);
s2 = series (4, id);
s3 = series (5, id);
s4 = series (6, id);
pid = 4. * s1 - 2. * s2 - s3 - s4;
pid = pid - (int) pid + 1.;
ihex (pid, NHX, chx);
printf (" position = %i\n fraction = %.15f \n hex digits = %10.10s\n time = %d",
id, pid, chx, (clock() - time) );
getchar();
}

void ihex (double x, int nhx, char chx[])
/* This returns, in chx, the first nhx hex digits of the fraction of x. */
{
int i;
double y;
char hx[] = "0123456789ABCDEF";

y = fabs (x);

for (i = 0; i < nhx; i++){
y = 16. * (y - floor (y));
chx[i] = hx[(int) y];
}
}

double series (int m, int id)
/* This routine evaluates the series sum_k 16^(id-k)/(8*k+m)
using the modular exponentiation technique. */
{
int k;
double ak, eps, p, s, t;
double expm (double x, double y);
#define eps 1e-17

s = 0.;

/* Sum the series up to id. */

for (k = 0; k < id; k++)
{
ak = 8 * k + m;
p = id - k;
t = expm (p, ak);
s = s + t / ak;
s = s - (int) s;
}

/* Compute a few terms where k >= id. */

for (k = id; k <= id + 100; k++){
ak = 8 * k + m;
t = pow (16., (double) (id - k)) / ak;
if (t < eps) break;
s = s + t;
s = s - (int) s;
}
return s;
}

double expm (double p, double ak)
/* expm = 16^p mod ak. This routine uses the left-to-right binary
exponentiation scheme. */
{
int i, j;
double p1, pt, r;
#define ntp 25
static double tp[ntp];
static int tp1 = 0;

/* If this is the first call to expm, fill the power of two table tp. */

if (tp1 == 0) {
tp1 = 1;
tp[0] = 1.;

for (i = 1; i < ntp; i++)
tp[i] = 2. * tp[i-1];
}

if (ak == 1.) return 0.;

/* Find the greatest power of two less than or equal to p. */

for (i = 0; i < ntp; i++) if (tp[i] > p) break;

pt = tp[i-1];
p1 = p;
r = 1.;

/* Perform binary exponentiation algorithm modulo ak. */

for (j = 1; j <= i; j++)
{
if (p1 >= pt){
r = 16. * r;
r = r - (int) (r / ak) * ak;
p1 = p1 - pt;
}
pt = 0.5 * pt;
if (pt >= 1.){
r = r * r;
r = r - (int) (r / ak) * ak;
}
}

return r;
}


Calcola la milionesima cifra di pigreco (e altre 11 a seguire). Il sorgente l'ho preso dal sito del tizio che ha inventato la formula.

Compilando col gcc 3.4.4 impiega 5.2s a calcolarla.
Col gcc 2.95 in 4.1s! Com'è possibile?

Ovviamente ho messo le ottimizzazioni in entrambi.

scorpion89
15-09-2006, 21:36
Uhm... sorge un problema.

Calcola la milionesima cifra di pigreco (e altre 11 a seguire). Il sorgente l'ho preso dal sito del tizio che ha inventato la formula.

Compilando col gcc 3.4.4 impiega 5.2s a calcolarla.
Col gcc 2.95 in 4.1s! Com'è possibile?

Ovviamente ho messo le ottimizzazioni in entrambi.
Prova a compilare con un 4.x.

Ciao

Vash1986
15-09-2006, 22:36
Prova a compilare con un 4.x.

Ciao

Esiste su windows? Mi sembra che il 3.4.2 sia l'ultima versione del port gnu gcc per win.

Al momento non posso switchare a linux xkè c'è un certo asinello che lavora a pieno ritmo :D

Ti farò sapere.

Anche perchè 5,2s sarebbe umiliante, C# fa in 5,1s :D

Vash1986
17-09-2006, 15:24
Intanto grosse novità dal test Array management.

Creazione matrice (array 2 dimensioni) 100x100int (10.000 int).
Inizializzazione di tutti i suoi indici con numeri random.
I numeri verranno poi ordinati in ordine crescente con la tecnica del Bubble Sort, algoritmo quadratico. Ergo alla peggio necessiterà di 10.000^2 iterazioni (100.000.000).
La matrice che ne risulta, verrà invertita 5 mila volte.

Tutto questo casotto, impiega la bellezza di 5 secondi in C++.

E indovinate quanto in C#? 17 secondi :D

marco.r
17-09-2006, 17:09
se puo' interessare, ci sono gia' un paio di progetti simili:
su windows: http://dada.perl.it/shootout/
su linux: http://shootout.alioth.debian.org/

Vash1986
17-09-2006, 18:33
molto molto interessante