From 57aaec48d0b26e46f8e9d96bc19b82d90f85066e Mon Sep 17 00:00:00 2001 From: rabot Date: Wed, 7 Oct 2026 11:51:31 +0200 Subject: [PATCH] Remplacement de la recherche dichotomique par une table de hachage --- analyseur.c | 73 +++++++++------ notes.md | 63 ++++++++++++- out/analyseur | Bin 27048 -> 27312 bytes out/gmon.out | Bin 8495 -> 8692 bytes out/profil_apres_hachage.txt | 172 +++++++++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+), 27 deletions(-) create mode 100644 out/profil_apres_hachage.txt diff --git a/analyseur.c b/analyseur.c index 435d719..ba4c84f 100644 --- a/analyseur.c +++ b/analyseur.c @@ -26,6 +26,8 @@ #define NB_MOTS_VOCAB 7000 #define TAILLE_MOT 32 #define MAX_MOTS_UNIQUES 20000 +/* Toujours moins de 50 % de cases occupées, même au maximum de mots. */ +#define TAILLE_HACHAGE (2 * MAX_MOTS_UNIQUES + 1) #define GRAINE 20261006UL /* ------------------------------------------------------------------------ */ @@ -235,44 +237,54 @@ int est_mot_vide(const char *mot) return 0; } -/* Le tableau reste trié alphabétiquement pendant le comptage. - * Renvoie l'indice du mot, ou -(position d'insertion + 1) s'il est absent. */ -int chercher_mot(Entree *table, int nb_entrees, const char *mot) +unsigned int hacher_mot(const char *mot) { - int debut = 0; - int fin = nb_entrees - 1; - - while (debut <= fin) { - int milieu = debut + (fin - debut) / 2; - int comparaison = comparer(table[milieu].mot, mot); - if (comparaison == 0) - return milieu; - if (comparaison < 0) - debut = milieu + 1; - else - fin = milieu - 1; + unsigned int h = 2166136261u; + for (int i = 0; mot[i] != '\0'; i++) { + h ^= (unsigned char)mot[i]; + h *= 16777619u; } - return -(debut + 1); + return h; } -void compter_mot(Entree *table, int *nb_entrees, const char *mot) +/* L'index contient indice + 1 ; zéro désigne une case libre. + * Renvoie l'indice du mot, ou -(case libre + 1) s'il est absent. */ +int chercher_mot(const Entree *table, const int *index_mots, const char *mot) { - int indice = chercher_mot(table, *nb_entrees, mot); + int position = hacher_mot(mot) % TAILLE_HACHAGE; + + while (index_mots[position] != 0) { + int indice = index_mots[position] - 1; + if (egales(table[indice].mot, mot)) + return indice; + /* Collision : essayer la case suivante, avec retour au début. */ + position = (position + 1) % TAILLE_HACHAGE; + } + return -(position + 1); +} + +void compter_mot(Entree *table, int *nb_entrees, int *index_mots, const char *mot) +{ + int indice = chercher_mot(table, index_mots, mot); if (indice >= 0) { table[indice].occurrences++; } else { - indice = -indice - 1; - /* Décaler uniquement lors de la première apparition d'un mot. */ - for (int i = *nb_entrees; i > indice; i--) - table[i] = table[i - 1]; + if (*nb_entrees >= MAX_MOTS_UNIQUES) { + fprintf(stderr, "Trop de mots distincts (maximum : %d).\n", + MAX_MOTS_UNIQUES); + exit(EXIT_FAILURE); + } + int position = -indice - 1; + indice = *nb_entrees; copier(table[indice].mot, mot); table[indice].occurrences = 1; + index_mots[position] = indice + 1; (*nb_entrees)++; } } -void compter_mots_ligne(Entree *table, int *nb_entrees, const char *ligne, - long *nb_mots_total) +void compter_mots_ligne(Entree *table, int *nb_entrees, int *index_mots, + const char *ligne, long *nb_mots_total) { char mot[TAILLE_MOT]; int i = 0; @@ -290,7 +302,7 @@ void compter_mots_ligne(Entree *table, int *nb_entrees, const char *ligne, if (k > 0) { (*nb_mots_total)++; if (!est_mot_vide(mot)) - compter_mot(table, nb_entrees, mot); + compter_mot(table, nb_entrees, index_mots, mot); } } } @@ -428,11 +440,20 @@ int main(void) normaliser_ligne(lignes[i]); Entree *table = malloc(MAX_MOTS_UNIQUES * sizeof(Entree)); + int *index_mots = calloc(TAILLE_HACHAGE, sizeof(int)); + if (table == NULL || index_mots == NULL) { + fprintf(stderr, "Allocation du tableau de comptage impossible.\n"); + free(table); + free(index_mots); + exit(EXIT_FAILURE); + } int nb_entrees = 0; long nb_mots_total = 0; for (int i = 0; i < nb_lignes; i++) - compter_mots_ligne(table, &nb_entrees, lignes[i], &nb_mots_total); + compter_mots_ligne(table, &nb_entrees, index_mots, lignes[i], &nb_mots_total); + /* Le tri déplace les entrées : l'index ne sert que pendant le comptage. */ + free(index_mots); trier_entrees(table, nb_entrees); double moyenne = longueur_moyenne(table, nb_entrees); diff --git a/notes.md b/notes.md index ae60154..60a6664 100644 --- a/notes.md +++ b/notes.md @@ -218,4 +218,65 @@ Empreinte du rapport : 1d53de903efd2b7c real 0m1.251s user 0m1.214s sys 0m0.004s -``` \ No newline at end of file +``` + +## Remplacement de la dichotomie par une table de hachage + +Un index de 40 001 cases associe chaque mot à son entrée dans le tableau. +`hacher_mot` calcule un entier à partir des caractères du mot ; le modulo +donne la première case à examiner. Chaque case contient l'indice de +l'entrée + 1, ou zéro si elle est libre. + +En cas de collision, `chercher_mot` vérifie le mot avec `egales()` puis +avance à la case suivante, en revenant au début si nécessaire. Deux mots +ayant le même hachage restent donc bien distincts. Les nouveaux mots sont +ajoutés à la fin du tableau, sans décaler les entrées existantes. + +La recherche et l'insertion sont en O(1) en moyenne pour ces mots de +longueur bornée, avec un pire cas en O(n) en cas de nombreuses collisions. +La limite de 20 000 mots distincts est vérifiée avant chaque nouvelle +insertion ; avec 40 001 cases, l'index reste rempli à moins de 50 %. + +Ce choix ajoute `40 001 * sizeof(int)` octets, soit environ 156 Kio sur +cette machine. L'index est libéré après le comptage, avant le tri final +qui déplace les entrées. L'empreinte du rapport est conservée, mais cette +version utilise davantage de mémoire pendant le comptage. + +Profil enregistré dans [out/profil_apres_hachage.txt](out/profil_apres_hachage.txt). +La comparaison porte sur la version précédente avec dichotomie et moyenne +calculée une seule fois, conservée dans `out/profil_apres_moyenne.txt`. + +| Mesure | Dichotomie | Hachage | +| --- | ---: | ---: | +| Appels de `chercher_mot` | 150 182 | 150 182 | +| Comparaisons de chaînes dans `chercher_mot` | 1 718 447 (`comparer`) | 153 101 (`egales`) | +| Temps réel médian sans profiling (`gcc -O0`, 5 exécutions par version) | 0,888 s | 0,831 s | + +Les recherches font environ 11,2 fois moins de comparaisons. Le temps +total baisse d'environ 6,4 % : le gain reste limité car la normalisation +et le tri occupent désormais l'essentiel du temps. L'ordre d'arrivée des +mots remplace l'ordre alphabétique pendant le comptage ; le tri final +effectue donc un nombre différent de comparaisons, tout en produisant +le même classement. + +Les cinq mesures, réalisées en alternant les deux versions sur la même +machine, sont respectivement : 0,883 / 0,892 / 0,888 / 0,883 / 0,888 s +avant, et 0,831 / 0,830 / 0,831 / 0,832 / 0,829 s après. + +Validation : compilation sans avertissement avec `-Wall -Wextra -Wpedantic`, +rapport et sortie console identiques octet par octet sur les dix +exécutions et avec `-pg`. L'empreinte reste **`1d53de903efd2b7c`**. +Des tests temporaires sous AddressSanitizer et UndefinedBehaviorSanitizer +ont vérifié les collisions avec retour à la première case, les doublons, +les mots de 0/1/31 caractères, 10 000 comptages comparés à une référence +linéaire, les 20 000 entrées possibles et le refus d'un dépassement. +Le programme complet a également été exécuté avec ces deux outils, +sans erreur et avec une sortie identique. + +Commandes pour reproduire ce profil : + +```bash +mkdir -p out/apres_hachage +gcc -O0 -pg analyseur.c -o out/apres_hachage/analyseur +(cd out/apres_hachage && ./analyseur && gprof -b ./analyseur gmon.out > ../profil_apres_hachage.txt) +``` diff --git a/out/analyseur b/out/analyseur index b792c3bc60372332af9f14e30525a7032d6490ad..5d9206f8f419a8ca8b82d365437d9c084f904538 100755 GIT binary patch delta 7163 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 TqRD|-=A2E?(n4vnV2V5dBB(h} diff --git a/out/gmon.out b/out/gmon.out index e7a376477298a842100edf85c3b5613824890752..03ef1ab71f368ef0dab08b7cb55cd3d3f7d73652 100644 GIT binary patch literal 8692 zcmYe#&Cg?GzyT6$AQBS%3=Am@3=GAo$@zIH#SlRT1~>yIFiMYxz-S1JhQMeDjE2By z2#kinXb6mkz-S1JhQMeDjE2By2#kgRwL<{szy-A}8esFd7(hPdU|?jBrJ74XCSo%T zA`T%L!1iKOg-;Bo7oQqRt1V{}5`sNr^+dw=JCe_Uh z3`|H`Kqesb$*VJv3>;jTsCKj2obW zUyubGR3R$rpn?(73=E71&;*YKGB7X-s6kXVLX80nHb4bo+Ck+V;{-Ip2^W|d7%!j+ zzG`J;U=&b?m6{dO+ z8Z77l72F985QuiDU!5njlb`-&P$SM~=Rdzr_3#{@0RB(eSl6C`Y2 H3_vOY$X{Y_ literal 8495 zcmYe#&Cg?Gzy+)!5(oGg7*ZG*7>ZMq^Yc=QA%YAHa0X0ZlpYO%(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVC7fzc2c4S~@R7!84u6au&hRWL(=i-DPefq|WYi9rNY5>14#xeyf) z5>+!cF;o@EJcw!t2@*%JKs;p31mz%9AXrc-5-3Xal3>lKQg8^2hBi1D28b9up^wWY zxWuUyVEE0)FH0>qU^j<8cEfCe(IB^g*dPpIgD^51#K(pqY9J&;9>Ru@5D{vV5VIj9 z#B5|XM1+BXkpWgez(huA+JykN7@(bPqb84rz-R~zR0uEzs6ec)Rf5nPGZ+{c3!s8q zkOdu7Au8;kf)UaT42%tEg2w_G7#J@=1s$QrfCU}YP_=_f8O8uK!3h_b85k#^3BGD& zWMI62Cb-OtiGfi-9o0;*pn(Re;KvXK21W-o!THt942%o3ASzcu-N{fV&cJv8Dp&^< zd>$;!!1w_w2n(f8m&6$u4YVQJWt1Uw`q}Laj0d2CyP<;XEuvN{oSlQ9%zP$P85p4iE>ZAQ#jau=WE`L6}7+t!o$<1N0% +[1] 98.6 0.00 0.72 main [1] + 0.00 0.44 21746/21746 normaliser_ligne [3] + 0.07 0.12 1/1 trier_entrees [4] + 0.00 0.07 21746/21746 compter_mots_ligne [7] + 0.01 0.00 1/1 decouper_lignes [12] + 0.00 0.01 1/1 generer_vocabulaire [15] + 0.00 0.00 1/1 construire_rapport [16] + 0.00 0.00 1/1 longueur_moyenne [18] + 0.00 0.00 1/1 ecart_type_longueur [17] + 0.00 0.00 1/1 generer_texte [26] + 0.00 0.00 1/1 racine [27] + 0.00 0.00 1/1 analyser_bigrammes [24] + 0.00 0.00 1/1 empreinte [25] +----------------------------------------------- + 0.00 0.00 5866/1599863 longueur_moyenne [18] + 0.00 0.00 5866/1599863 ecart_type_longueur [17] + 0.01 0.00 26801/1599863 ajouter [14] + 0.44 0.00 1561330/1599863 normaliser_ligne [3] +[2] 61.6 0.45 0.00 1599863 longueur [2] +----------------------------------------------- + 0.00 0.44 21746/21746 main [1] +[3] 60.2 0.00 0.44 21746 normaliser_ligne [3] + 0.44 0.00 1561330/1599863 longueur [2] + 0.00 0.00 1539584/5297256 est_lettre [19] + 0.00 0.00 1266663/1266663 en_minuscule [20] +----------------------------------------------- + 0.07 0.12 1/1 main [1] +[4] 26.7 0.07 0.12 1 trier_entrees [4] + 0.05 0.07 17202045/17202045 doit_echanger [5] +----------------------------------------------- + 0.05 0.07 17202045/17202045 trier_entrees [4] +[5] 17.1 0.05 0.07 17202045 doit_echanger [5] + 0.07 0.00 12172087/12172087 comparer [6] +----------------------------------------------- + 0.07 0.00 12172087/12172087 doit_echanger [5] +[6] 10.3 0.07 0.00 12172087 comparer [6] +----------------------------------------------- + 0.00 0.07 21746/21746 main [1] +[7] 8.9 0.00 0.07 21746 compter_mots_ligne [7] + 0.04 0.01 250000/250000 est_mot_vide [8] + 0.00 0.01 150182/150182 compter_mot [11] +----------------------------------------------- + 0.04 0.01 250000/250000 compter_mots_ligne [7] +[8] 7.5 0.04 0.01 250000 est_mot_vide [8] + 0.01 0.00 12045671/12198772 egales [9] +----------------------------------------------- + 0.00 0.00 153101/12198772 chercher_mot [10] + 0.01 0.00 12045671/12198772 est_mot_vide [8] +[9] 2.1 0.01 0.00 12198772 egales [9] +----------------------------------------------- + 0.01 0.00 150182/150182 compter_mot [11] +[10] 1.4 0.01 0.00 150182 chercher_mot [10] + 0.00 0.00 153101/12198772 egales [9] + 0.00 0.00 150182/150182 hacher_mot [22] +----------------------------------------------- + 0.00 0.01 150182/150182 compter_mots_ligne [7] +[11] 1.4 0.00 0.01 150182 compter_mot [11] + 0.01 0.00 150182/150182 chercher_mot [10] + 0.00 0.00 5866/32667 copier [23] +----------------------------------------------- + 0.01 0.00 1/1 main [1] +[12] 1.4 0.01 0.00 1 decouper_lignes [12] +----------------------------------------------- + +[13] 1.4 0.01 0.00 _init [13] +----------------------------------------------- + 0.00 0.00 5867/26801 construire_rapport [16] + 0.00 0.01 20934/26801 generer_vocabulaire [15] +[14] 1.0 0.00 0.01 26801 ajouter [14] + 0.01 0.00 26801/1599863 longueur [2] + 0.00 0.00 26801/32667 copier [23] +----------------------------------------------- + 0.00 0.01 1/1 main [1] +[15] 0.8 0.00 0.01 1 generer_vocabulaire [15] + 0.00 0.01 20934/26801 ajouter [14] + 0.00 0.00 27934/928117 alea [21] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[16] 0.2 0.00 0.00 1 construire_rapport [16] + 0.00 0.00 5867/26801 ajouter [14] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[17] 0.2 0.00 0.00 1 ecart_type_longueur [17] + 0.00 0.00 5866/1599863 longueur [2] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[18] 0.2 0.00 0.00 1 longueur_moyenne [18] + 0.00 0.00 5866/1599863 longueur [2] +----------------------------------------------- + 0.00 0.00 1539584/5297256 normaliser_ligne [3] + 0.00 0.00 3757672/5297256 analyser_bigrammes [24] +[19] 0.0 0.00 0.00 5297256 est_lettre [19] +----------------------------------------------- + 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 [15] + 0.00 0.00 900183/928117 generer_texte [26] +[21] 0.0 0.00 0.00 928117 alea [21] +----------------------------------------------- + 0.00 0.00 150182/150182 chercher_mot [10] +[22] 0.0 0.00 0.00 150182 hacher_mot [22] +----------------------------------------------- + 0.00 0.00 5866/32667 compter_mot [11] + 0.00 0.00 26801/32667 ajouter [14] +[23] 0.0 0.00 0.00 32667 copier [23] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[24] 0.0 0.00 0.00 1 analyser_bigrammes [24] + 0.00 0.00 3757672/5297256 est_lettre [19] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[25] 0.0 0.00 0.00 1 empreinte [25] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[26] 0.0 0.00 0.00 1 generer_texte [26] + 0.00 0.00 900183/928117 alea [21] +----------------------------------------------- + 0.00 0.00 1/1 main [1] +[27] 0.0 0.00 0.00 1 racine [27] +----------------------------------------------- + +Index by function name + + [13] _init [23] copier [26] generer_texte + [14] ajouter [12] decouper_lignes [15] generer_vocabulaire + [21] alea [5] doit_echanger [22] hacher_mot + [24] analyser_bigrammes [17] ecart_type_longueur [2] longueur + [10] chercher_mot [9] egales [18] longueur_moyenne + [6] comparer [25] empreinte [3] normaliser_ligne + [11] compter_mot [20] en_minuscule [27] racine + [7] compter_mots_ligne [19] est_lettre [4] trier_entrees + [16] construire_rapport [8] est_mot_vide