7.4 KiB
Lancement du programme après la compilation avec gcc -O0 analyseur.c -o analyseur
Lignes analysées : 21746
Mots au total : 250000
Mots distincts : 5866
Longueur moyenne : 6.712 (écart-type 1.873)
Bigramme le + courant : "me" (17607 fois, souvent suivi de 'n')
Top 10 :
1. rane 287
2. fasi 241
3. tata 219
4. mopo 214
5. cofi 180
6. vesi 179
7. laganomo 177
8. boto 172
9. nopebo 169
10. rotion 165
Empreinte du rapport : 1d53de903efd2b7c
Et ensuite la commande time sur l'exécutable avec time ./analyseur
Lignes analysées : 21746
Mots au total : 250000
Mots distincts : 5866
Longueur moyenne : 6.712 (écart-type 1.873)
Bigramme le + courant : "me" (17607 fois, souvent suivi de 'n')
Top 10 :
1. rane 287
2. fasi 241
3. tata 219
4. mopo 214
5. cofi 180
6. vesi 179
7. laganomo 177
8. boto 172
9. nopebo 169
10. rotion 165
Empreinte du rapport : 1d53de903efd2b7c
real 0m2.858s
user 0m2.821s
sys 0m0.013s
On recompile avec le flag -pg : gcc -O0 -pg analyseur.c -o analyseur
Et on relance time dessus
Lignes analysées : 21746
Mots au total : 250000
Mots distincts : 5866
Longueur moyenne : 6.712 (écart-type 1.873)
Bigramme le + courant : "me" (17607 fois, souvent suivi de 'n')
Top 10 :
1. rane 287
2. fasi 241
3. tata 219
4. mopo 214
5. cofi 180
6. vesi 179
7. laganomo 177
8. boto 172
9. nopebo 169
10. rotion 165
Empreinte du rapport : 1d53de903efd2b7c
real 0m6.354s
user 0m6.295s
sys 0m0.020s
On lance gprof : gprof -b ./analyseur gmon.out > profil_avant.txt
Optimisation de chercher_mot : recherche dichotomique
La recherche initiale parcourait toutes les entrées jusqu'à trouver le mot.
Pour 150 182 recherches, elle effectuait 296 656 203 appels à egales().
Le tableau est maintenant maintenu dans l'ordre alphabétique pendant le
comptage. chercher_mot utilise comparer() pour éliminer la moitié des
entrées restantes à chaque étape : la recherche passe de O(n) à O(log n).
Si le mot est absent, la fonction renvoie -(position d'insertion + 1) ;
compter_mot retrouve cette position avec -indice - 1, décale les entrées
et insère le nouveau mot. Cette insertion reste en O(n), mais elle n'a lieu
qu'à la première apparition de chacun des 5 866 mots distincts.
Le tableau existant est réutilisé, sans allocation supplémentaire.
Le tri final par fréquence produit le même classement.
Résultats du nouveau profil, conservé dans out/profil_apres.txt :
| Mesure | Avant | Après |
|---|---|---|
Appels de chercher_mot |
150 182 | 150 182 |
Appels à egales() depuis chercher_mot |
296 656 203 | 0 |
Comparaisons de chaînes dans chercher_mot |
296 656 203 | 1 718 447 |
Appels à egales() dans tout le programme |
308 701 874 | 12 045 671 |
Temps réel sans profiling (gcc -O0) |
2,80 s | 1,45 s |
Les recherches effectuent environ 173 fois moins de comparaisons.
Les appels restants à egales() viennent de est_mot_vide.
Les temps ci-dessus correspondent à une mesure avant/après sur la même
machine pendant cette modification : environ 48 % de temps en moins
(accélération d'environ 1,93). Ce sont des mesures ponctuelles.
Validation : compilation avec -Wall -Wextra -Wpedantic, rapport et sortie
console identiques octet par octet à la version initiale, avec et sans -pg.
L'empreinte reste 1d53de903efd2b7c.
Un test temporaire sous AddressSanitizer et UndefinedBehaviorSanitizer a
également vérifié les recherches dans un tableau vide, les mots présents
ou absents, les insertions au début/milieu/fin, les doublons et les mots de
31 caractères, puis comparé 10 000 comptages à une référence linéaire.
Pour reproduire le profil sans écraser les fichiers du profil initial :
mkdir -p out/apres
gcc -O0 -pg analyseur.c -o out/apres/analyseur
(cd out/apres && ./analyseur && gprof -b ./analyseur gmon.out > ../profil_apres.txt)
Lignes analysées : 21746
Mots au total : 250000
Mots distincts : 5866
Longueur moyenne : 6.712 (écart-type 1.873)
Bigramme le + courant : "me" (17607 fois, souvent suivi de 'n')
Top 10 :
1. rane 287
2. fasi 241
3. tata 219
4. mopo 214
5. cofi 180
6. vesi 179
7. laganomo 177
8. boto 172
9. nopebo 169
10. rotion 165
Empreinte du rapport : 1d53de903efd2b7c
real 0m1.986s
user 0m1.934s
sys 0m0.011s
Optimisation des appels à longueur_moyenne
longueur_moyenne parcourt les mots une fois par appel. Le coût excessif
venait de ecart_type_longueur, qui recalculait cette même moyenne à
chaque itération, soit 5 866 fois. Avec l'appel de main, cela représentait
5 867 calculs de moyenne et 34 415 822 appels à longueur().
main calcule désormais la moyenne une seule fois et la transmet en
paramètre à ecart_type_longueur. La boucle utilise directement cette
valeur. Le calcul des statistiques passe ainsi de O(n²) à O(n), sans
allocation supplémentaire ni modification de la formule de variance.
Profil enregistré dans out/profil_apres_moyenne.txt.
La colonne « Avant » correspond à la version déjà optimisée pour
chercher_mot, dont le profil reste dans out/profil_apres.txt.
| Mesure | Avant | Après |
|---|---|---|
Appels à longueur_moyenne |
5 867 | 1 |
Appels à longueur() depuis longueur_moyenne |
34 415 822 | 5 866 |
Appels à longueur() dans tout le programme |
36 009 819 | 1 599 863 |
Temps réel sans profiling (gcc -O0) |
1,46 s | 0,88 s |
Cette mesure ponctuelle sur la même machine donne environ 40 % de temps en moins, soit une accélération d'environ 1,66 par rapport à l'étape précédente.
Validation : compilation avec -Wall -Wextra -Wpedantic sans avertissement,
puis comparaison du rapport et de la sortie console avant/après, avec et
sans -pg. Ils restent identiques octet par octet, y compris la moyenne
(6.712) et l'écart-type (1.873). L'empreinte reste 1d53de903efd2b7c.
Commandes pour reproduire ce profil :
mkdir -p out/apres_moyenne
gcc -O0 -pg analyseur.c -o out/apres_moyenne/analyseur
(cd out/apres_moyenne && ./analyseur && gprof -b ./analyseur gmon.out > ../profil_apres_moyenne.txt)
[rabot@salle235-06 out]$ time ./analyseur
Lignes analysées : 21746
Mots au total : 250000
Mots distincts : 5866
Longueur moyenne : 6.712 (écart-type 1.873)
Bigramme le + courant : "me" (17607 fois, souvent suivi de 'n')
Top 10 :
1. rane 287
2. fasi 241
3. tata 219
4. mopo 214
5. cofi 180
6. vesi 179
7. laganomo 177
8. boto 172
9. nopebo 169
10. rotion 165
Empreinte du rapport : 1d53de903efd2b7c
real 0m1.251s
user 0m1.214s
sys 0m0.004s