Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

vitesse c++ vs Java

14 réponses
Avatar
xfredox
Bonjour,

j'ai essayé de faire un programme qui me calcule la somme de la série
harmonique sur des grands nombres. Quelle n'a pas été ma surprise de
constater que le programme en C++ était environ deux fois plus long que
le même programme qu'en java
Je suis à peu près certain que cela ne vient pas du programme (j'en ai
fait un de mon crû et plusieurs récupérés sur internet)
pourriez-vous m'expliquer cela ? il est vrai que je ne maîtrise pas les
subtilités du compilateur étant novice en la matière, cela pourrait-il
venir de cela ?

par avance, merci
Fred

10 réponses

1 2
Avatar
Marc
xfredox wrote:

j'ai essayé de faire un programme qui me calcule la somme de la série
harmonique sur des grands nombres. Quelle n'a pas été ma surprise de
constater que le programme en C++ était environ deux fois plus long que
le même programme qu'en java
Je suis à peu près certain que cela ne vient pas du programme (j'en ai
fait un de mon crû et plusieurs récupérés sur internet)
pourriez-vous m'expliquer cela ? il est vrai que je ne maîtrise pas les
subtilités du compilateur étant novice en la matière, cela pourrait-il
venir de cela ?



Bonjour,

les programmes ne doivent pas être bien longs, ça aiderait de pouvoir y
jeter un oeil avant de répondre. La notion de "grand nombre" est en
particulier assez floue...

Le nom du compilateur, les options, la machine dessous, sont d'autres
infos qui pourraient servir.
Avatar
xfredox
Le 01/09/2012 15:33, Marc a écrit :
xfredox wrote:

j'ai essayé de faire un programme qui me calcule la somme de la série
harmonique sur des grands nombres. Quelle n'a pas été ma surprise de
constater que le programme en C++ était environ deux fois plus long que
le même programme qu'en java
Je suis à peu près certain que cela ne vient pas du programme (j'en ai
fait un de mon crû et plusieurs récupérés sur internet)
pourriez-vous m'expliquer cela ? il est vrai que je ne maîtrise pas les
subtilités du compilateur étant novice en la matière, cela pourrait-il
venir de cela ?



Bonjour,

les programmes ne doivent pas être bien longs, ça aiderait de pouvoir y
jeter un oeil avant de répondre. La notion de "grand nombre" est en
particulier assez floue...

Le nom du compilateur, les options, la machine dessous, sont d'autres
infos qui pourraient servir.





Bonsoir,

Ci-dessous le code en java: (9 secondes)

public class premier
{
public static void main (String[] args)
{
int i;
float b=0;
for (i=1;i<2000000000;i++)//
{b=b+(float)+1/i;}
System.out.println(b);
}
}

Maintenant le code en C++: (15 secondes)

#include <iostream>
using namespace std;
int main()
{
int i;
float b=0;
for(i=1;i<2000000000;i++)
{
b=b+(float)1/i;
}

cout << "Resultat: "<< b<< endl;

return 0;
}

Je suis sous ubuntu 12.04 64
J'utilise eclipse pour java et code:block pour c++
A noter que si je passe en ligne de commande les temps sont relativement
les mêmes (à quelques dixièmes de secondes)
(en ligne de commande j'utilise java 6 et g++)
J'ai les mêmes résultats sous w7

Comment expliquer une telle différence ? Comment y remédier ?
par avance, merci
Fred
Avatar
espie
In article <5042505f$0$2381$,
xfredox wrote:
Le 01/09/2012 15:33, Marc a écrit :
xfredox wrote:

j'ai essayé de faire un programme qui me calcule la somme de la série
harmonique sur des grands nombres. Quelle n'a pas été ma surprise de
constater que le programme en C++ était environ deux fois plus long que
le même programme qu'en java
Je suis à peu près certain que cela ne vient pas du programme (j'en ai
fait un de mon crû et plusieurs récupérés sur internet)
pourriez-vous m'expliquer cela ? il est vrai que je ne maîtrise pas les
subtilités du compilateur étant novice en la matière, cela pourrait-il
venir de cela ?



Bonjour,

les programmes ne doivent pas être bien longs, ça aiderait de pouvoir y
jeter un oeil avant de répondre. La notion de "grand nombre" est en
particulier assez floue...

Le nom du compilateur, les options, la machine dessous, sont d'autres
infos qui pourraient servir.





Bonsoir,

Ci-dessous le code en java: (9 secondes)

public class premier
{
public static void main (String[] args)
{
int i;
float b=0;
for (i=1;i<2000000000;i++)//
{b=b+(float)+1/i;}
System.out.println(b);
}
}

Maintenant le code en C++: (15 secondes)

#include <iostream>
using namespace std;
int main()
{
int i;
float b=0;
for(i=1;i<2000000000;i++)
{
b=b+(float)1/i;
}

cout << "Resultat: "<< b<< endl;

return 0;
}

Je suis sous ubuntu 12.04 64
J'utilise eclipse pour java et code:block pour c++
A noter que si je passe en ligne de commande les temps sont relativement
les mêmes (à quelques dixièmes de secondes)
(en ligne de commande j'utilise java 6 et g++)
J'ai les mêmes résultats sous w7

Comment expliquer une telle différence ? Comment y remédier ?
par avance, merci
Fred



Toujours aucunes options de compile (qui sont sans doute differentes).

De facon plus interessante, ca ne sert pas a grand chose d'avoir un programme
qui affiche un resultat completement faux.

Je viens de regarder ton code C++:
Resultat: 15.4037
et avec des double:
Resultat: 21.9936

La deuxieme valeur etant relativement proche de la realite,
qui est ln 2000000000 + gamma =~ 21.9941
a 1/4000000000 pres...
Avatar
xfredox
Le 01/09/2012 20:38, Marc Espie a écrit :
In article <5042505f$0$2381$,
xfredox wrote:
Le 01/09/2012 15:33, Marc a écrit :
xfredox wrote:

j'ai essayé de faire un programme qui me calcule la somme de la série
harmonique sur des grands nombres. Quelle n'a pas été ma surprise de
constater que le programme en C++ était environ deux fois plus long que
le même programme qu'en java
Je suis à peu près certain que cela ne vient pas du programme (j'en ai
fait un de mon crû et plusieurs récupérés sur internet)
pourriez-vous m'expliquer cela ? il est vrai que je ne maîtrise pas les
subtilités du compilateur étant novice en la matière, cela pourrait-il
venir de cela ?



Bonjour,

les programmes ne doivent pas être bien longs, ça aiderait de pouvoir y
jeter un oeil avant de répondre. La notion de "grand nombre" est en
particulier assez floue...

Le nom du compilateur, les options, la machine dessous, sont d'autres
infos qui pourraient servir.





Bonsoir,

Ci-dessous le code en java: (9 secondes)

public class premier
{
public static void main (String[] args)
{
int i;
float b=0;
for (i=1;i<2000000000;i++)//
{b=b+(float)+1/i;}
System.out.println(b);
}
}

Maintenant le code en C++: (15 secondes)

#include <iostream>
using namespace std;
int main()
{
int i;
float b=0;
for(i=1;i<2000000000;i++)
{
b=b+(float)1/i;
}

cout << "Resultat: "<< b<< endl;

return 0;
}

Je suis sous ubuntu 12.04 64
J'utilise eclipse pour java et code:block pour c++
A noter que si je passe en ligne de commande les temps sont relativement
les mêmes (à quelques dixièmes de secondes)
(en ligne de commande j'utilise java 6 et g++)
J'ai les mêmes résultats sous w7

Comment expliquer une telle différence ? Comment y remédier ?
par avance, merci
Fred



Toujours aucunes options de compile (qui sont sans doute differentes).

De facon plus interessante, ca ne sert pas a grand chose d'avoir un programme
qui affiche un resultat completement faux.

Je viens de regarder ton code C++:
Resultat: 15.4037
et avec des double:
Resultat: 21.9936

La deuxieme valeur etant relativement proche de la realite,
qui est ln 2000000000 + gamma =~ 21.9941
a 1/4000000000 pres...




Je viens de faire quelques tests après quelques recherches sur le web:

code:block ne met aucune option d'optimisation par défaut (un g++ en
ligne de commande sans option équivaut à l'IDE puisque les temps
d'exécution sont les mêmes)
en ligne de commande je ne mettais aucune option car je n'aurais jamais
pensé qu'il y avait une telle différence (et surtout je ne les
connaissais pas)

Dans un premier temps je suis passé au type double (en fait à partir
d'un certain moment le float ne sert plus à rien dans l'addition d'un
inverse dans ce cas là) donc c'est comme si il ne se passait plus rien.
Le double est donc plus adapté (merci pour la remarque, je n'y avais pas
pensé)

En ligne de commande
java: 17s
sans optimisation:
c++ 20
Java gagne encore

Eclipse java :14s
Code:block c++ 20s
Bizarre...

Avec optimisation:
g++ -O3 -s main.cpp 13s
g++ -Ofast -s main.cpp 7s

Eclipse doit faire une ou deux petite(s) optimisation(s) puisque c'est
plus rapide que la ligne de commande (et dire que je pensais qu'un IDE
c'était forcément plus long)

Par contre effectivement dans le meilleur des cas, le C++ devient deux
fois plus rapide que Java, impressionnant ! (et logique)
J'ai trouvé l'option fast en cherchant dans le man de g++, par contre je
ne sais pas exactement comment elle fonctionne en dehors du fait qu'elle
augmente de façon tangible la vitesse (je n'ai pas vraiment trouvé de
description dessus sur le net), une idée ?

peut-on encore faire mieux ?

bonne soirée
Avatar
Fabien LE LEZ
On Sat, 01 Sep 2012 21:35:11 +0200, xfredox :

J'ai trouvé l'option fast en cherchant dans le man de g++



http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Optimize-Options.html
-Ofast
Disregard strict standards compliance. -Ofast enables all -O3
optimizations. It also enables optimizations that are not valid for
all standard compliant programs. It turns on -ffast-math.
Avatar
xfredox
Le 01/09/2012 21:41, Fabien LE LEZ a écrit :
On Sat, 01 Sep 2012 21:35:11 +0200, xfredox :

J'ai trouvé l'option fast en cherchant dans le man de g++



http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Optimize-Options.html
-Ofast
Disregard strict standards compliance. -Ofast enables all -O3
optimizations. It also enables optimizations that are not valid for
all standard compliant programs. It turns on -ffast-math.





Merci , comme ça en plus je saurais où regarder pour toutes les autres
options (c t pas complet sur la commande man)
et en français ça donne quoi ? :D
Avatar
espie
In article <5042636f$0$1854$,
xfredox wrote:
g++ -O3 -s main.cpp 13s
g++ -Ofast -s main.cpp 7s

Eclipse doit faire une ou deux petite(s) optimisation(s) puisque c'est
plus rapide que la ligne de commande (et dire que je pensais qu'un IDE
c'était forcément plus long)

Par contre effectivement dans le meilleur des cas, le C++ devient deux
fois plus rapide que Java, impressionnant ! (et logique)
J'ai trouvé l'option fast en cherchant dans le man de g++, par contre je
ne sais pas exactement comment elle fonctionne en dehors du fait qu'elle
augmente de façon tangible la vitesse (je n'ai pas vraiment trouvé de
description dessus sur le net), une idée ?



Tout processeur moderne est "pipeline" avec l'execution de plusieurs
instructions qui se chevauchent.

Dans un code comme 1/i, tu peux avoir des divisions par zero, donc
stricto-sensu, tu peux etre amene a mettre un "stop" pour dire au
processeur de finir l'instruction et s'assurer qu'il n'y a pas de
division par zero avant de continuer.

C'est globalement surtout ce genre de choses que va faire -ffast-math...

En tres simplifie, pour du calcul "standard" dans des conditions
usuelles, ca va marcher. Pour des trucs un peu aux limites, -ffast-math
peut te donner un resultat (faux) la ou ca devrait foirer...

c'est tout un domaine un peu orthogonal au C++ lui-meme, les calculs
flottants etant generalement couverts par une autre norme, IEEE 754.
Avatar
Marc
Marc Espie wrote:

Par contre effectivement dans le meilleur des cas, le C++ devient deux
fois plus rapide que Java, impressionnant ! (et logique)
J'ai trouvé l'option fast en cherchant dans le man de g++, par contre je
ne sais pas exactement comment elle fonctionne en dehors du fait qu'elle
augmente de façon tangible la vitesse (je n'ai pas vraiment trouvé de
description dessus sur le net), une idée ?





Le "fast" signifie que les opérations sur les float et les double
peuvent faire n'importe quoi, tant que ça va vite. Avec de la chance, ça
reste assez proche d'un résultat sensé. Parfois non.

Tout processeur moderne est "pipeline" avec l'execution de plusieurs
instructions qui se chevauchent.

Dans un code comme 1/i, tu peux avoir des divisions par zero, donc
stricto-sensu, tu peux etre amene a mettre un "stop" pour dire au
processeur de finir l'instruction et s'assurer qu'il n'y a pas de
division par zero avant de continuer.

C'est globalement surtout ce genre de choses que va faire -ffast-math...



Bof. Là c'est surtout l'associativité de l'addition qui joue. Avec
fast-math, le compilateur suppose que (a+b)+c == a+(b+c) == b+(a+c).
Cela lui permet de vectoriser le code en travaillant sur des quadruplets
(i,i+1,i+2,i+3). Il utilise aussi une instruction qui donne une
approximation de 1/x (plus une itération pour raffiner) au lieu de la
vraie valeur.
Avatar
Fabien LE LEZ
On Sat, 01 Sep 2012 21:43:34 +0200, xfredox :

et en français ça donne quoi



Essaie http://translate.google.com/
Avatar
Jean-Marc Desperrier
xfredox a écrit :
et en français ça donne quoi ? :D



C'est plus rapide, mais il n'est pas sur que cela marche encore.

Déjà que les optimisations parfaitement autorisées par le standard
donnent régulièrement des résultats qui semblent inattendus pour les
développeurs, mais si le programme s'autorise à ne pas les respecter ...

Je ne dirais qu'on ne peut s'autoriser l'option que pour de tout petit
morceaux de programme pour lequel on a des test de conformité où on
vérifie la conformité dans tous les cas de figure possible.

Ca me fait penser qu'un vraiment bon compilateur remplacerait tout ton
code, et en restant totalement "standard compliant", par :
printf("Resultat: 21.9936");
1 2