Newsgroup: it.comp.lang.c++
Titolo: prestazioni del C++

Ho voluto fare una prova comparativa con i vari compilatori per dimostrare
come la convinzione che il C++ produca programmi piů grossi e lenti sia errata.
(O meglio, sia dovuta a compilatori C++ non eccellenti)
Ecco il programma C++ usato
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
  ifstream in("file.zip", ios::in | ios::binary);
  size_t size = 0;
  char ch;
  clock_t start = clock();
  if(start == clock_t(-1)) exit(1);
  while(in.get(ch)) ++size;
  clock_t finish = clock();
  if(finish == clock_t(-1)) exit(1);
  std::cout << "size:  " << size << '\n';
  std::cout << "time:  " << double(finish - start) / CLOCKS_PER_SEC << '\n';
}
e per confronto ecco il programma C
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
  FILE* in = fopen("file.zip", "rb");
  size_t size = 0;
  int ch;
  clock_t start, finish;
  start = clock();
  if(start == -1) exit(1);
  while( (ch = getc(in)) != EOF) ++size;
  finish = clock();
  if(finish == -1) exit(1);
  printf("size:  %u\n", size);
  printf("time:  %f\n", (double)(finish - start) / CLOCKS_PER_SEC);
  return 0;
}
I compilatori che ho usato sono il BCC 5.5 e DJGPP sotto Windows 98
e GNU C++ e KAI C++ 4.0 sotto Linux Mandrake 7.0.
Ho misurato sia la dimensione dell'eseguibile sia il tempo impiegato nella lettura
di un file zip (creato in Windows) di 208856013 byte.
Nota: ho fatto due misure.
Ecco i risultati:
Windows 98:
  BCC32 -O2 prest.c
     -grandezza dell'exe:  56320 byte
     -tempo impiegato:     19.75 - 33.405
  BCC32 -O2 prest.cpp
     -grandezza dell'exe:  143360 byte
     -tempo impiegato:     242.28 - "non effettuata"
  gpp -O3 prest.c
     -grandezza dell'exe:  107860 byte
     -tempo impiegato:     "non effettuate"
  gpp -O3 prest.cpp
     -grandezza dell'exe:  285436 byte
     -tempo impiegato:     "non effettuate"
Linux:   (il file zip č stato copiato da Windows in una directory di Linux)
  cc -O3 prest.c
     -grandezza dell'exe:  11897 byte
     -tempo impiegato:     85.03 - 90.11
  cc -O3 prest.cpp
     -grandezza dell'exe:  13921 byte
     -tempo impiegato:     138.05 - 137.77
  KCC -O3 +K3 prest.c
     -grandezza dell'exe:  12613 byte
     -tempo impiegato:     "non effettuate"
  KCC -O3 +K3 prest.cpp
     -grandezza dell'exe:  15368 byte
     -tempo impiegato:     82.17 - 82.15
La cosa čiů importante č il confronto fra GNU C ed il KAI C++.
La dimensione dell'eseguibile č di poco piů grande e le prestazioni
sono le stesse.
Saluti  Manlio Perillo

 (O meglio, sia dovuta a compilatori C++ non eccellenti)
Ehm... queste prove andrebbero effettuate con prudenza...
Innanzitutto, lavorando su sistemi operativi multitask, non hai misurato la
durata del tuo processo, ma hai misurato il tempo impiegato ad eseguire il
tuo processo. Che differenza passa tra i due? Che la CPU esegue
alternativamente tutti i processi correntemente in esecuzione, e anche se a
te sembra di aver lanciato solo il tuo programma, ce ne sono sempre anche
altri in esecuzione (ad esempio, "iexplore" nel caso di win98, le Norton
utilities e così via...) così il tempo che hai misurato è stato speso non
solo per il tuo programma.
Poi tu hai realizzato un'applicazione estremamente I/O bound, cioè
contenente praticamente solo operazioni di I/O (lettura di file). Il tempo
per queste operazioni dipende *estremamente* dl sistema operativo e niente
dal linguaggio utilizzato.
Quando un programma esegue un'istruzione del tipo "read(file,variabile)"
(almeno sotto LINUX che è un po' più furbo) il programma fa una richiesta al
sistema operativo. Questo *blocca* il tuo programma e lo mette in attesa.
Nel frattempo pone in esecuzione un altro processo e attiva il controller
del disco che faccia la lettura. Quando il controller del disco ha finito ed
è il tuo turno per l'esecuzione, il sistema operativo dice al tuo programma:
"Guarda, sul disco c'era scritto *Pippo* " e il tuo programma prosegue.
Infine quando si dice che il C++ è più lento del C, si intende che è più
lento se si usano dei costrutti peculiari del C++ (e che il C non ha). Il
classico esempio è dato dalle funzioni membro virtuali.
Poiché il C è un sottoinsieme del C++ ( più o meno ), un compilatore C++ può
compilare un programma C (come nel tuo esempio), perciò ti assicuro che
molti compilatori, cambiando l'estensione del file sorgente, l'unica cosa
che cambiano è il controllo delle parole chiave, ma il codice generato è
identico.
Comunque il C non è più efficiente del C++. Magari una determinata
applicazione può risultare dell'1% meno veloce a causa del polimorfismo, ma
è anche vero che nel 99.9% dei casi (pure nei videogiochi!) l'1% della
velocità in meno non incide quanto i benefici che un progetto realmente ad
oggetti porta in termini di manutenibilità, riusabilità e chiarezza del
codice!
Daniele.