forked from menault/2026_TD1_DEV51_Qualite_Algo
Remplacement de la recherche dichotomique par une table de hachage
This commit is contained in:
@@ -218,4 +218,65 @@ Empreinte du rapport : 1d53de903efd2b7c
|
||||
real 0m1.251s
|
||||
user 0m1.214s
|
||||
sys 0m0.004s
|
||||
```
|
||||
```
|
||||
|
||||
## 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)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user