Grosse différence de performance entre un CGI en C et C++

Grosse différence de performance entre un CGI en C et C++ - C++ - Programmation

Marsh Posté le 26-04-2003 à 05:29:05    

J'ai voulu testé si ça valait le coup de réécrire un CGI Perl en C++. Et surprise, c'etait presque pareil ! :ouch:
J'ai alors codé un petit CGI de test en C, C++ et Perl.  
 
J'ai testé ses performances avec la commande (sous Apache + Linux) :
# ab -n500 http://localhost/cgi-bin/programme
 
Les résultats (sur un vieux PII 400) se passent de commentaire :
Programme en C++ :

Code :
  1. Time taken for tests:   14.909 seconds
  2. Complete requests:      500
  3. Failed requests:        0
  4. Broken pipe errors:     0
  5. Total transferred:      2336500 bytes
  6. HTML transferred:       2247000 bytes
  7. Requests per second:    33.54 [#/sec] (mean)
  8. Time per request:       29.82 [ms] (mean)
  9. Time per request:       29.82 [ms] (mean, across all concurrent requests)
  10. Transfer rate:          156.72 [Kbytes/sec] received


C :

Code :
  1. Time taken for tests:   4.598 seconds
  2. Complete requests:      500
  3. Failed requests:        0
  4. Broken pipe errors:     0
  5. Total transferred:      2451000 bytes
  6. HTML transferred:       2361500 bytes
  7. Requests per second:    108.74 [#/sec] (mean)
  8. Time per request:       9.20 [ms] (mean)
  9. Time per request:       9.20 [ms] (mean, across all concurrent requests)
  10. Transfer rate:          533.06 [Kbytes/sec] received


Perl :

Code :
  1. Time taken for tests:   14.963 seconds
  2. Complete requests:      500
  3. Failed requests:        0
  4. Broken pipe errors:     0
  5. Total transferred:      2779000 bytes
  6. HTML transferred:       2689500 bytes
  7. Requests per second:    33.42 [#/sec] (mean)
  8. Time per request:       29.93 [ms] (mean)
  9. Time per request:       29.93 [ms] (mean, across all concurrent requests)
  10. Transfer rate:          185.72 [Kbytes/sec] received


 
La compilation s'est faite sous linux avec GCC et G++ 3.2 (option "-s -Os" ). Voila le code source (d'accord, ce programme est inutile et merdique, mais ça doit être suffisant pour faire un petit test, non ?) :
cpp :

Code :
  1. # include <iostream>
  2. using namespace std;
  3. void kalex(int * nb){
  4. if(*nb == 50){
  5.  cout << "[cinquante]";
  6. } else {
  7.  cout << "[" << (*nb * 3.1415) / 2.562254 << "]";
  8. }
  9. }
  10. int main(){
  11. {
  12.  cout << "Content-type: text/plain\n\n";
  13.  cout << "Hello Word!\n";
  14.  float multiple, result;
  15.  multiple = 6.569602;
  16.  result = multiple * 500;
  17.  cout << result << "\n";
  18. }
  19. int nb;
  20. for(nb = 0; nb < 100; nb++){
  21.  cout << "Le nombre actuel de cycle est de " << nb;
  22.  kalex(&nb);
  23.  cout << "\n";
  24. }
  25. return 0;
  26. }


C :

Code :
  1. # include <stdio.h>
  2. void kalex(int * nb){
  3. if(*nb == 50){
  4.  printf("[cinquante]" );
  5. } else {
  6.  printf("[%f]", (*nb * 3.1415) / 2.562254);
  7. }
  8. }
  9. int main(){
  10. {
  11.  printf("Content-type: text/plain\n\n" );
  12.  printf("Hello Word!\n" );
  13.  float multiple, result;
  14.  multiple = 6.569602;
  15.  result = multiple * 500;
  16.  printf("%f\n", result);
  17. }
  18. int nb;
  19. for(nb = 0; nb < 100; nb++){
  20.  printf("Le nombre actuel de cycle est de %i", nb);
  21.  kalex(&nb);
  22.  printf("\n" );
  23. }
  24. return 0;
  25. }


Perl :

Code :
  1. #!/usr/bin/perl
  2. print "Content-type: text/plain\n\n";
  3. print "Hello Word!\n";
  4. my $multiple;
  5. my $result;
  6. $multiple = 6.569602;
  7. $result = $multiple * 500;
  8. print $result."\n";
  9. my $nb;
  10. for($nb = 0; $nb < 100; $nb++){
  11. print "Le nombre actuel de cycle est de ".$nb;
  12. alex($nb);
  13. print "\n";
  14. }
  15. sub alex($nb){
  16. if($nb == 50){
  17.  print "[cinquante]";
  18. } else {
  19.  print "[".($nb * 3.1415) / 2.562254."]";
  20. }
  21. }


Je demande l'indulgence, je débute en C++. ;)
 
Qu'en pensez-vous ? C'est normal une telle différence ? Est-ce mon code qui est en cause ? Mon cerveau ? Ou le C++ ?


Message édité par kalex le 26-04-2003 à 05:31:21
Reply

Marsh Posté le 26-04-2003 à 05:29:05   

Reply

Marsh Posté le 26-04-2003 à 07:36:40    

ton code C++ est ok (sauf le passage par pointeur qui sert à rien, en C comme en C++, et à koi sert ce bloc supplémentaire dans le main. combien de test à tue effectué? quelles options de compilations?
 
cela dit, meme en C, ça me parait tres lent


Message édité par Taz le 26-04-2003 à 07:38:58
Reply

Marsh Posté le 26-04-2003 à 07:59:49    

J'ai compilé avec :
g++ -s -Os test.cpp -o cpp
gcc -s -Os test.c -o cc
 
Sinon le bloc supplémentaire, c'est pour libérer la mémoire à la fin, comme si les variables qu'il contient avaient été déclarées dans un if.
Enfin, je crois que bien que ça fait ça. :/ ;)
 
C'est vrai que c'est lent, mais n'oublie pas la machine : PII 400 MHz.
Et oui, j'ai fait et refais les tests. Idem. :/


Message édité par kalex le 26-04-2003 à 08:00:52
Reply

Marsh Posté le 26-04-2003 à 08:21:38    

essaye avec -03
 
quelle est la version de ton compilateur?
 
edit: pour etre strictement équivalent au C, il faut remplacer tes chaines à un caracteres "[" par un caractere '['


Message édité par Taz le 26-04-2003 à 08:23:17
Reply

Marsh Posté le 26-04-2003 à 08:34:20    

J'utilise GCC 3.2.
 
Si je remplace " par ' et compile avec -03, ça ne donne rien de vraiment mieux :

Code :
  1. Time taken for tests:   14.657 seconds
  2. Complete requests:      500
  3. Failed requests:        0
  4. Broken pipe errors:     0
  5. Total transferred:      2336500 bytes
  6. HTML transferred:       2247000 bytes
  7. Requests per second:    34.11 [#/sec] (mean)
  8. Time per request:       29.31 [ms] (mean)
  9. Time per request:       29.31 [ms] (mean, across all concurrent requests)
  10. Transfer rate:          159.41 [Kbytes/sec] received


En tout cas, merci de m'aider. :)

Reply

Marsh Posté le 26-04-2003 à 08:41:04    

de toutes façons, tu es confronté à un problème bien connu. la médiocrité de l'implémenation de E/S C++ [:spamafote]
 
si tu veux continuer à faire en C++, mais que les ostream sont vraiment trop lent à ton gout, continue à utiliser stdio.h avec quelque précautions: en debut de programme tu rajoutes
 
std::ios_base::sync_with_stdio();
 
pour assurer la cohérence iostream/cstdio


Message édité par Taz le 26-04-2003 à 08:42:04
Reply

Marsh Posté le 26-04-2003 à 08:54:30    

Je me demande si mon g++, n'a pas un problème. Parce que si je compile mon programme C (sans rien changer) avec g++ ça me donne :

Code :
  1. Time taken for tests:   10.487 seconds
  2. Complete requests:      500
  3. Failed requests:        0
  4. Broken pipe errors:     0
  5. Total transferred:      2451000 bytes
  6. HTML transferred:       2361500 bytes
  7. Requests per second:    47.68 [#/sec] (mean)
  8. Time per request:       20.97 [ms] (mean)
  9. Time per request:       20.97 [ms] (mean, across all concurrent requests)
  10. Transfer rate:          233.72 [Kbytes/sec] received


J'en déduis donc (à tort ?) que les problèmes d'E/S, ne sont responsables que d'un tiers du ralentissement.

Reply

Marsh Posté le 26-04-2003 à 09:05:08    

yep, bizarre....


Message édité par Taz le 26-04-2003 à 09:05:22
Reply

Marsh Posté le 26-04-2003 à 09:12:57    

c'est vrai que y a un truc là. le code assembleur est exactement le meme pourtant. tu veux pas faire des tests 50 fois plus long pour avoir des chiffres plus precis

Reply

Marsh Posté le 26-04-2003 à 09:37:23    

J'ai pas fait des tests 50 fois plus longs, mais bien 10 fois, et c'est pareil. Les résultats sont d'ailleurs très réguliers.
 
Et les fichiers binaires sont bien différents :
avec g++ : 3368 Ko
avec gcc : 3052 Ko
Il s'agit du même code source.
D'ailleurs ces deux fichiers ne sont pas un peu gros ?
 
Edit: En fait c'est :
avec g++ : 3368 octets
avec gcc : 3052 octets
 
Halala, je devrais me relire des fois. :o


Message édité par kalex le 26-04-2003 à 10:01:02
Reply

Marsh Posté le 26-04-2003 à 09:37:23   

Reply

Marsh Posté le 26-04-2003 à 09:51:02    

voir énormes!!!!! donne moi ta ligne de compilation s'il te plait

Reply

Marsh Posté le 26-04-2003 à 09:57:25    

Merde, j'ai mal dormi moi... C'est des octets et non des Ko. :o
Excuse-moi. :o

Reply

Marsh Posté le 26-04-2003 à 10:50:08    

tu peux faire strip ./a.out et redonner les tailles?

Reply

Marsh Posté le 26-04-2003 à 13:33:33    

Je compile avec l'option -s, donc strip ne fait rien.

Reply

Marsh Posté le 26-04-2003 à 19:13:12    

Les objets standard du C++ ne valent pas un clou. A refaire.
 
Il me semble que le mécanisme CGI est mauvais.


Message édité par sr16 le 26-04-2003 à 19:14:33

---------------
TOPIC PERMANENT Matrox Parhelia
Reply

Marsh Posté le 26-04-2003 à 19:15:31    

ou t'as vu un objet la?

Reply

Marsh Posté le 26-04-2003 à 20:47:29    

++Taz a écrit :

ou t'as vu un objet la?


 
"cout" dans le cas de son prog en C++


---------------
TOPIC PERMANENT Matrox Parhelia
Reply

Marsh Posté le 26-04-2003 à 20:48:37    

la on parle du meme programme C ompilé avec gcc ou g++

Reply

Marsh Posté le 27-04-2003 à 03:47:41    

J'ai essayé G++ 2.96, et le programme C++ compilé est 2.5 fois plus rapide qu'avec G++ 3.2 !!! Ce qui me donne un programme « seulement » 40 % plus lents que celui en C (rapport 5 à 7).
De plus, la compilation est quasiment instantanée avec G++ 2.96 alors qu'elle met quelques secondes avec G++ 3.2. :/
 
Ça vient peut-être de ma conf (par défaut, j'y ai pas touché) :

Code :
  1. $ g++ -v
  2. Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.2/specs
  3. Configured with: ../configure --prefix=/usr --libdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-long-long --enable-__cxa_atexit --enable-languages=c,c++,ada,f77,objc,java --host=i586-mandrake-linux-gnu --with-system-zlib
  4. Thread model: posix
  5. gcc version 3.2 (Mandrake Linux 9.0 3.2-1mdk)


Je ferais bien des tests, mais je n'ai pas compris où et comment modifier ça.


Message édité par kalex le 27-04-2003 à 03:48:39
Reply

Marsh Posté le 27-04-2003 à 03:49:36    

Sr16 a écrit :

Les objets standard du C++ ne valent pas un clou. A refaire.
 
Il me semble que le mécanisme CGI est mauvais.

Si les mécanismes object de C++ ne valent rien, quel langage object et rapide choisir ? Pareil pour les CGI, y a pas d'alternative ?

Reply

Marsh Posté le 27-04-2003 à 08:33:48    

essaye de voir sur le site de gcc si d'autres personnes constatent ce problème ou s'il y a eu un rapport de bug

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed