diff --git a/analyseur.c b/analyseur.c index 9d6e0e7..435d719 100644 --- a/analyseur.c +++ b/analyseur.c @@ -331,11 +331,12 @@ double longueur_moyenne(const Entree *table, int n) return (double)total / n; } -double ecart_type_longueur(const Entree *table, int n) +/* Réutiliser la moyenne calculée dans main évite de la recalculer par mot. */ +double ecart_type_longueur(const Entree *table, int n, double moyenne) { double somme = 0.0; for (int i = 0; i < n; i++) { - double ecart = longueur(table[i].mot) - longueur_moyenne(table, n); + double ecart = longueur(table[i].mot) - moyenne; somme += ecart * ecart; } return somme / n; /* variance ; la racine est prise dans main */ @@ -435,7 +436,7 @@ int main(void) trier_entrees(table, nb_entrees); double moyenne = longueur_moyenne(table, nb_entrees); - double ecart_type = racine(ecart_type_longueur(table, nb_entrees)); + double ecart_type = racine(ecart_type_longueur(table, nb_entrees, moyenne)); char trigramme[4]; int occ_trigramme; diff --git a/notes.md b/notes.md index 3eabc97..ae60154 100644 --- a/notes.md +++ b/notes.md @@ -152,4 +152,70 @@ 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](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 : + +```bash +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) +``` + +```bash +[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 ``` \ No newline at end of file diff --git a/out/analyseur b/out/analyseur index b3a384c..b792c3b 100755 Binary files a/out/analyseur and b/out/analyseur differ diff --git a/out/gmon.out b/out/gmon.out index 57d1a6b..e7a3764 100644 Binary files a/out/gmon.out and b/out/gmon.out differ diff --git a/out/profil_apres_moyenne.txt b/out/profil_apres_moyenne.txt new file mode 100644 index 0000000..041505e --- /dev/null +++ b/out/profil_apres_moyenne.txt @@ -0,0 +1,162 @@ +Flat profile: + +Each sample counts as 0.01 seconds. + % cumulative self self total + time seconds seconds calls ms/call ms/call name + 61.33 0.46 0.46 1599863 0.00 0.00 longueur + 12.00 0.55 0.09 9860216 0.00 0.00 comparer + 8.00 0.61 0.06 1 60.00 164.31 trier_entrees + 4.00 0.64 0.03 17202045 0.00 0.00 doit_echanger + 4.00 0.67 0.03 12045671 0.00 0.00 egales + 4.00 0.70 0.03 150182 0.00 0.00 compter_mot + 1.33 0.71 0.01 5297256 0.00 0.00 est_lettre + 1.33 0.72 0.01 250000 0.00 0.00 est_mot_vide + 1.33 0.73 0.01 150182 0.00 0.00 chercher_mot + 1.33 0.74 0.01 1 10.00 17.09 analyser_bigrammes + 1.33 0.75 0.01 1 10.00 10.00 generer_texte + 0.00 0.75 0.00 1266663 0.00 0.00 en_minuscule + 0.00 0.75 0.00 928117 0.00 0.00 alea + 0.00 0.75 0.00 32667 0.00 0.00 copier + 0.00 0.75 0.00 26801 0.00 0.00 ajouter + 0.00 0.75 0.00 21746 0.00 0.00 compter_mots_ligne + 0.00 0.75 0.00 21746 0.00 0.02 normaliser_ligne + 0.00 0.75 0.00 1 0.00 1.69 construire_rapport + 0.00 0.75 0.00 1 0.00 0.00 decouper_lignes + 0.00 0.75 0.00 1 0.00 1.69 ecart_type_longueur + 0.00 0.75 0.00 1 0.00 0.00 empreinte + 0.00 0.75 0.00 1 0.00 6.02 generer_vocabulaire + 0.00 0.75 0.00 1 0.00 1.69 longueur_moyenne + 0.00 0.75 0.00 1 0.00 0.00 racine + + Call graph + + +granularity: each sample hit covers 4 byte(s) for 1.33% of 0.75 seconds + +index % time self children called name + +[1] 100.0 0.00 0.75 main [1] + 0.00 0.45 21746/21746 normaliser_ligne [3] + 0.06 0.10 1/1 trier_entrees [4] + 0.00 0.10 21746/21746 compter_mots_ligne [6] + 0.01 0.01 1/1 analyser_bigrammes [12] + 0.01 0.00 1/1 generer_texte [14] + 0.00 0.01 1/1 generer_vocabulaire [16] + 0.00 0.00 1/1 construire_rapport [17] + 0.00 0.00 1/1 longueur_moyenne [19] + 0.00 0.00 1/1 ecart_type_longueur [18] + 0.00 0.00 1/1 decouper_lignes [23] + 0.00 0.00 1/1 racine [25] + 0.00 0.00 1/1 empreinte [24] +----------------------------------------------- + 0.00 0.00 5866/1599863 longueur_moyenne [19] + 0.00 0.00 5866/1599863 ecart_type_longueur [18] + 0.01 0.00 26801/1599863 ajouter [15] + 0.45 0.00 1561330/1599863 normaliser_ligne [3] +[2] 61.3 0.46 0.00 1599863 longueur [2] +----------------------------------------------- + 0.00 0.45 21746/21746 main [1] +[3] 60.2 0.00 0.45 21746 normaliser_ligne [3] + 0.45 0.00 1561330/1599863 longueur [2] + 0.00 0.00 1539584/5297256 est_lettre [13] + 0.00 0.00 1266663/1266663 en_minuscule [20] +----------------------------------------------- + 0.06 0.10 1/1 main [1] +[4] 21.9 0.06 0.10 1 trier_entrees [4] + 0.03 0.07 17202045/17202045 doit_echanger [5] +----------------------------------------------- + 0.03 0.07 17202045/17202045 trier_entrees [4] +[5] 13.9 0.03 0.07 17202045 doit_echanger [5] + 0.07 0.00 8141769/9860216 comparer [7] +----------------------------------------------- + 0.00 0.10 21746/21746 main [1] +[6] 12.8 0.00 0.10 21746 compter_mots_ligne [6] + 0.03 0.03 150182/150182 compter_mot [8] + 0.01 0.03 250000/250000 est_mot_vide [9] +----------------------------------------------- + 0.02 0.00 1718447/9860216 chercher_mot [11] + 0.07 0.00 8141769/9860216 doit_echanger [5] +[7] 12.0 0.09 0.00 9860216 comparer [7] +----------------------------------------------- + 0.03 0.03 150182/150182 compter_mots_ligne [6] +[8] 7.4 0.03 0.03 150182 compter_mot [8] + 0.01 0.02 150182/150182 chercher_mot [11] + 0.00 0.00 5866/32667 copier [22] +----------------------------------------------- + 0.01 0.03 250000/250000 compter_mots_ligne [6] +[9] 5.3 0.01 0.03 250000 est_mot_vide [9] + 0.03 0.00 12045671/12045671 egales [10] +----------------------------------------------- + 0.03 0.00 12045671/12045671 est_mot_vide [9] +[10] 4.0 0.03 0.00 12045671 egales [10] +----------------------------------------------- + 0.01 0.02 150182/150182 compter_mot [8] +[11] 3.4 0.01 0.02 150182 chercher_mot [11] + 0.02 0.00 1718447/9860216 comparer [7] +----------------------------------------------- + 0.01 0.01 1/1 main [1] +[12] 2.3 0.01 0.01 1 analyser_bigrammes [12] + 0.01 0.00 3757672/5297256 est_lettre [13] +----------------------------------------------- + 0.00 0.00 1539584/5297256 normaliser_ligne [3] + 0.01 0.00 3757672/5297256 analyser_bigrammes [12] +[13] 1.3 0.01 0.00 5297256 est_lettre [13] +----------------------------------------------- + 0.01 0.00 1/1 main [1] +[14] 1.3 0.01 0.00 1 generer_texte [14] + 0.00 0.00 900183/928117 alea [21] +----------------------------------------------- + 0.00 0.00 5867/26801 construire_rapport [17] + 0.00 0.01 20934/26801 generer_vocabulaire [16] +[15] 1.0 0.00 0.01 26801 ajouter [15] + 0.01 0.00 26801/1599863 longueur [2] + 0.00 0.00 26801/32667 copier [22] +----------------------------------------------- + 0.00 0.01 1/1 main [1] +[16] 0.8 0.00 0.01 1 generer_vocabulaire [16] + 0.00 0.01 20934/26801 ajouter [15] + 0.00 0.00 27934/928117 alea [21] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[17] 0.2 0.00 0.00 1 construire_rapport [17] + 0.00 0.00 5867/26801 ajouter [15] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[18] 0.2 0.00 0.00 1 ecart_type_longueur [18] + 0.00 0.00 5866/1599863 longueur [2] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[19] 0.2 0.00 0.00 1 longueur_moyenne [19] + 0.00 0.00 5866/1599863 longueur [2] +----------------------------------------------- + 0.00 0.00 1266663/1266663 normaliser_ligne [3] +[20] 0.0 0.00 0.00 1266663 en_minuscule [20] +----------------------------------------------- + 0.00 0.00 27934/928117 generer_vocabulaire [16] + 0.00 0.00 900183/928117 generer_texte [14] +[21] 0.0 0.00 0.00 928117 alea [21] +----------------------------------------------- + 0.00 0.00 5866/32667 compter_mot [8] + 0.00 0.00 26801/32667 ajouter [15] +[22] 0.0 0.00 0.00 32667 copier [22] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[23] 0.0 0.00 0.00 1 decouper_lignes [23] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[24] 0.0 0.00 0.00 1 empreinte [24] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[25] 0.0 0.00 0.00 1 racine [25] +----------------------------------------------- + +Index by function name + + [15] ajouter [22] copier [9] est_mot_vide + [21] alea [23] decouper_lignes [14] generer_texte + [12] analyser_bigrammes [5] doit_echanger [16] generer_vocabulaire + [11] chercher_mot [18] ecart_type_longueur [2] longueur + [7] comparer [10] egales [19] longueur_moyenne + [8] compter_mot [24] empreinte [3] normaliser_ligne + [6] compter_mots_ligne [20] en_minuscule [25] racine + [17] construire_rapport [13] est_lettre [4] trier_entrees