Indexer les mots par une table de hachage dans compter_mot

chercher_mot parcourait toute la table pour chaque mot : 296,7 millions
d'appels à egales pour 150 182 mots. Une table de hachage à adressage
ouvert (hachage FNV-1a, la fonction empreinte déjà présente) donne une
recherche en temps constant en moyenne. L'ordre d'insertion dans la table
est conservé.

Temps : 5,6 s → 2,0 s. Empreinte inchangée (1d53de903efd2b7c).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 13:59:34 +02:00
parent 330254a918
commit 255a73982c
+19 -9
View File
@@ -235,24 +235,34 @@ int est_mot_vide(const char *mot)
return 0; return 0;
} }
int chercher_mot(Entree *table, int nb_entrees, const char *mot) /* Table de hachage à adressage ouvert : chaque case contient l'indice + 1
* d'un mot de la table, ou 0 si elle est vide. Sa taille est une puissance
* de 2 nettement supérieure à MAX_MOTS_UNIQUES pour garder des sondages courts. */
#define TAILLE_HACHAGE 32768
static int index_mots[TAILLE_HACHAGE];
unsigned long empreinte(const char *s);
/* Renvoie la case de index_mots qui contient mot, ou la case vide où l'ajouter. */
unsigned long chercher_mot(const Entree *table, const char *mot)
{ {
for (int i = 0; i < nb_entrees; i++) { unsigned long h = empreinte(mot) & (TAILLE_HACHAGE - 1);
if (egales(table[i].mot, mot)) while (index_mots[h] != 0 && !egales(table[index_mots[h] - 1].mot, mot))
return i; h = (h + 1) & (TAILLE_HACHAGE - 1);
} return h;
return -1;
} }
void compter_mot(Entree *table, int *nb_entrees, const char *mot) void compter_mot(Entree *table, int *nb_entrees, const char *mot)
{ {
int indice = chercher_mot(table, *nb_entrees, mot); unsigned long h = chercher_mot(table, mot);
if (indice >= 0) { if (index_mots[h] != 0) {
table[indice].occurrences++; table[index_mots[h] - 1].occurrences++;
} else { } else {
copier(table[*nb_entrees].mot, mot); copier(table[*nb_entrees].mot, mot);
table[*nb_entrees].occurrences = 1; table[*nb_entrees].occurrences = 1;
(*nb_entrees)++; (*nb_entrees)++;
index_mots[h] = *nb_entrees;
} }
} }