dimanche 6 mai 2012

Java vs C

Petite expérience pour voir les différences de perf entre le Java et le C sur des traitement de calculs. Résultats étonnants.

Pour mesurer les perfs, j'ai fait un programme qui calculs les nombres premiers. Il est globalement le même en Java et en C. Je n'ai pas cherché à optimiser le code à part quelques astuces dans l'algo sur les deux langages. Après 10 secondes de calcul, le programme donne le nombre de nombres premiers calculés et le dernier trouvé.

Résultats
Java : 2751346 45582233
C : 2616720 43213853


Xint
Le programme en Java semble plus performant que le programme en C. Ceci est possible grâce aux optimisations et à la compilation à la volée (JIT). Pour désactiver la compilation à la volée, on peut utiliser l'option -Xint.

Java -Xint : 776456 11810987


GCJ
Petit test avec GCJ qui permet de compiler le Java en code natif.

Java GCJ : 2721147 45052451


Conclusion : pas de conclusion. héhé.



Programme C


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

#define MEMPLUS 100000

unsigned int * ajouterPremier(unsigned int * premiers, int nbPremiers, unsigned int nouveau, int *tailleAllouee) {
if(*tailleAllouee < nbPremiers+1) {
unsigned int *premiers2;
int k;

premiers2 = malloc(sizeof(unsigned int) * (*tailleAllouee+MEMPLUS));
for(k=0;k<nbPremiers;k++) {
premiers2[k] = premiers[k];
}
premiers2[nbPremiers] = nouveau;
*tailleAllouee = *tailleAllouee + MEMPLUS;
free(premiers);
return premiers2;
} else {
premiers[nbPremiers] = nouveau;
return premiers;
}
}


int main(int argc, char **argv)
{
printf("debut c\n");
time_t t = time(NULL);
int i;
unsigned int enCours = 5;
unsigned int racineEnCours = 2;

unsigned int *premiers;

int nbPremiers = 2;
int tailleAllouee = MEMPLUS;
char estPremier = 1;
int pas = 4;

premiers = malloc(sizeof(unsigned int) * tailleAllouee);
premiers[0] = 2;
premiers[1] = 3;

while (difftime(time(NULL),t) < 10) {
estPremier = 1;
for (i=1; i < nbPremiers && racineEnCours >= premiers[i]; i++) {
if (enCours % premiers[i] == 0) {
estPremier = 0;
break;
}
}
if (estPremier == 1) {
premiers = ajouterPremier(premiers,nbPremiers,enCours,&tailleAllouee);
nbPremiers++;
}
pas = 6 - pas;
enCours += pas;
racineEnCours = sqrt(enCours);
}
printf("%d %u",nbPremiers,premiers[nbPremiers-1]);
free(premiers);
return 0;
}





Programme Java


import java.lang.Math;

public class Perf {

public static int tailleAllouee = 1000;
public static final int MEMPLUS = 100000;

public static int [] ajouterPremier(int [] premiers, int nbPremiers, int nouveau) {
if(Perf.tailleAllouee < nbPremiers+1) {
int [] premiers2 =  new int[Perf.tailleAllouee + Perf.MEMPLUS];
for(int i=0;i<nbPremiers;i++) {
premiers2[i] = premiers[i];
}
premiers2[nbPremiers] = nouveau;
Perf.tailleAllouee = Perf.tailleAllouee + Perf.MEMPLUS;
return premiers2;
} else {
premiers[nbPremiers] = nouveau;
return premiers;
}
}

public static void main (String args[]) {
System.out.println("debut java");
long t = System.currentTimeMillis();
int enCours = 5;
int [] premiers = new int[Perf.MEMPLUS];
int nbPremiers = 2;
premiers[0] = 2;
premiers[1] = 3;
boolean estPremier = true;
int racineEnCours = 2;
int pas = 4;

while (System.currentTimeMillis() - t < 10000) {
estPremier = true;
for (int i=0; i < nbPremiers && racineEnCours >= premiers[i] ; i++) {
if (enCours % premiers[i] == 0) {
estPremier = false;
break;
}
}
if (estPremier) {
premiers = Perf.ajouterPremier(premiers,nbPremiers,enCours);
nbPremiers++;
}
pas = 6 - pas;
enCours += pas;
racineEnCours = (int)Math.sqrt(enCours);
}
System.out.println(""+nbPremiers+" "+premiers[nbPremiers-1]);
}
}

Aucun commentaire:

Enregistrer un commentaire