bonjour,
Connaissez vous une implémentation robuste des tableaux associatifs
(table de hachage - collections d'éléments avec une indexation non
entière) en C ?
En bref, quelque chose qui me permette de stocker et
retrouver "rapidement" un index de type chaîne de caractères
(comme par exemple : "1,106,-12,13,-123,14,89") au sein de la
structure.
bonjour,
Connaissez vous une implémentation robuste des tableaux associatifs
(table de hachage - collections d'éléments avec une indexation non
entière) en C ?
En bref, quelque chose qui me permette de stocker et
retrouver "rapidement" un index de type chaîne de caractères
(comme par exemple : "1,106,-12,13,-123,14,89") au sein de la
structure.
bonjour,
Connaissez vous une implémentation robuste des tableaux associatifs
(table de hachage - collections d'éléments avec une indexation non
entière) en C ?
En bref, quelque chose qui me permette de stocker et
retrouver "rapidement" un index de type chaîne de caractères
(comme par exemple : "1,106,-12,13,-123,14,89") au sein de la
structure.
Thomas LEDUC wrote:
Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Il y a par exemple la Kazlib :
doc module de hachage :
http://users.footprints.net/~kaz/kazlib_doc/node78.html
telechargement : http://users.footprints.net/~kaz/kazlib.html
En bref, quelque chose qui me permette de stocker et retrouver
"rapidement" un index de type chaîne de caractères (comme par
exemple : "1,106,-12,13,-123,14,89") au sein de la structure.
A faire soi-même ce n'est pas bien compliqué mis à part la
fonction de hachage qui va demander plus d'attention.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Thomas LEDUC wrote:
Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Il y a par exemple la Kazlib :
doc module de hachage :
http://users.footprints.net/~kaz/kazlib_doc/node78.html
telechargement : http://users.footprints.net/~kaz/kazlib.html
En bref, quelque chose qui me permette de stocker et retrouver
"rapidement" un index de type chaîne de caractères (comme par
exemple : "1,106,-12,13,-123,14,89") au sein de la structure.
A faire soi-même ce n'est pas bien compliqué mis à part la
fonction de hachage qui va demander plus d'attention.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Thomas LEDUC wrote:
Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Il y a par exemple la Kazlib :
doc module de hachage :
http://users.footprints.net/~kaz/kazlib_doc/node78.html
telechargement : http://users.footprints.net/~kaz/kazlib.html
En bref, quelque chose qui me permette de stocker et retrouver
"rapidement" un index de type chaîne de caractères (comme par
exemple : "1,106,-12,13,-123,14,89") au sein de la structure.
A faire soi-même ce n'est pas bien compliqué mis à part la
fonction de hachage qui va demander plus d'attention.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Targeur fou wrote:Thomas LEDUC wrote:Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Qui n'est pas un tableau haché, mais un arbre équilibré.
(N'empèche que pour jusqu'à quelque milliers d'éléments, on ne
remarque pas la différence en temps.)
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne. Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Quand j'aurais du temps, je veux réfaire les tests, en ajoutant
et des jeux de données et encore des hachages. J'ai constaté un
certain nombre d'anomalies, que j'aimerais investigué. (Donc,
par exemple, sur la plupart des jeux de données, A = 1047 était
aussi vite que les valeurs ci-dessus, mais avec un, et un seul
jeu de données, elle était prèsque 6 fois plus lente.) Aussi, je
n'ai mésuré que les temps d'accès (ce qui est après tout ce qui
nous intéresse le plus) ; j'aimerais instrumenté pour mésurer
aussi le nombre de comparaisons, etc.
Targeur fou wrote:
Thomas LEDUC wrote:
Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Qui n'est pas un tableau haché, mais un arbre équilibré.
(N'empèche que pour jusqu'à quelque milliers d'éléments, on ne
remarque pas la différence en temps.)
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne. Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Quand j'aurais du temps, je veux réfaire les tests, en ajoutant
et des jeux de données et encore des hachages. J'ai constaté un
certain nombre d'anomalies, que j'aimerais investigué. (Donc,
par exemple, sur la plupart des jeux de données, A = 1047 était
aussi vite que les valeurs ci-dessus, mais avec un, et un seul
jeu de données, elle était prèsque 6 fois plus lente.) Aussi, je
n'ai mésuré que les temps d'accès (ce qui est après tout ce qui
nous intéresse le plus) ; j'aimerais instrumenté pour mésurer
aussi le nombre de comparaisons, etc.
Targeur fou wrote:Thomas LEDUC wrote:Connaissez vous une implémentation robuste des tableaux
associatifs (table de hachage - collections d'éléments avec
une indexation non entière) en C ?
Je dirais bien std::map ;-) ...
Qui n'est pas un tableau haché, mais un arbre équilibré.
(N'empèche que pour jusqu'à quelque milliers d'éléments, on ne
remarque pas la différence en temps.)
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne. Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Quand j'aurais du temps, je veux réfaire les tests, en ajoutant
et des jeux de données et encore des hachages. J'ai constaté un
certain nombre d'anomalies, que j'aimerais investigué. (Donc,
par exemple, sur la plupart des jeux de données, A = 1047 était
aussi vite que les valeurs ci-dessus, mais avec un, et un seul
jeu de données, elle était prèsque 6 fois plus lente.) Aussi, je
n'ai mésuré que les temps d'accès (ce qui est après tout ce qui
nous intéresse le plus) ; j'aimerais instrumenté pour mésurer
aussi le nombre de comparaisons, etc.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne.
Pour la troisième, voirhttp://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a propos des
fonctions de hachage et utiliser N (taille de la table, i.e. nombre de
noeuds de liste primaires) premier avec une simple méthode additive
modulo N (méthode de Horner) semble être ce qu'il y a de mieux comme
compromis simplicité/efficacité.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne.
Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a propos des
fonctions de hachage et utiliser N (taille de la table, i.e. nombre de
noeuds de liste primaires) premier avec une simple méthode additive
modulo N (méthode de Horner) semble être ce qu'il y a de mieux comme
compromis simplicité/efficacité.
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
le même selon le jeu de données, mais la différence se tenait
toujours dans l'incertitude de la mésure. (Les deux premières
valeurs sont des primes de Mersenne.
Pour la troisième, voirhttp://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a propos des
fonctions de hachage et utiliser N (taille de la table, i.e. nombre de
noeuds de liste primaires) premier avec une simple méthode additive
modulo N (méthode de Horner) semble être ce qu'il y a de mieux comme
compromis simplicité/efficacité.
Targeur fou wrote:
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Presente des methodes trop couteuses sans reelle plus-value.
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
effectivement, ce sont toutes les constantes que j'ai retenues
pour des strings (j'utilise 31).
le même selon le jeu de données, mais la différence se
tenait toujours dans l'incertitude de la mésure. (Les deux
premières valeurs sont des primes de Mersenne.
Et d'utilisation particulierement rapide.
Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Vraie multiplication.
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
Targeur fou wrote:
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Presente des methodes trop couteuses sans reelle plus-value.
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
effectivement, ce sont toutes les constantes que j'ai retenues
pour des strings (j'utilise 31).
le même selon le jeu de données, mais la différence se
tenait toujours dans l'incertitude de la mésure. (Les deux
premières valeurs sont des primes de Mersenne.
Et d'utilisation particulierement rapide.
Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Vraie multiplication.
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
Targeur fou wrote:
Si tu cherches "hash functions"+C sous Google, tu auras des
liens intéressants dont celui-ci :
http://burtleburtle.net/bob/hash/doobs.html
Presente des methodes trop couteuses sans reelle plus-value.
C'est le grand problème avec le reseau ; on trouve tout, du bon
et du mauvais. D'après les tests que j'ai fait, sur une variété
de données, les meilleurs hachages se basaient sur un simple
application multiplicative :
h[i] = (A * h[i + 1] + c[i]) % 2^N ;
(ou c, c'était la chaîne à hacher, et c[i] le i-ième caractère).
Mais évidemment, pas pour n'importe quelle valeur de A:-). Tous
mes tests utilisaient N == 32 ; sur une machine de 32 bits,
faire le calcul sur des unsigned int fait le modulo
automatiquement. Pour A, j'ai eu de bons résultats avec des
valeurs 31, 127 et 16777619 ; le meilleur résultat n'était pas
effectivement, ce sont toutes les constantes que j'ai retenues
pour des strings (j'utilise 31).
le même selon le jeu de données, mais la différence se
tenait toujours dans l'incertitude de la mésure. (Les deux
premières valeurs sont des primes de Mersenne.
Et d'utilisation particulierement rapide.
Pour la troisième, voir
http://www.isthe.com/chongo/tech/comp/fnv/. Où d'ailleurs ils
utilisent un ^ à la place du + dans l'algorithme.)
Vraie multiplication.
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
Quand j'ai inventé l'utilisation des primes de Mersenne, je
travaillais sur un 8086. Et le compilateur ne savait pas
convertir les multiplications par une constante en des décalages
et des additions ou des soustractions. Là, il y avait
effectivement une différence de temps d'une facteur d'à peu près
cinq.J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
En général, on fait le calcul modulo 2^N, ou N est le nombre de
bits de la machine, ce qui veut dire que le modulo est gratuit.
Seulement une fois calculer sur la chaîne complète, on fait
modulo la taille de la table. Ça limite les dégats.
Mais en fait, j'utilise aussi systèmatiquement des tables de
taille 2^n, simplement parce que c'est plus facile à les faire
grandir -- je garde le hachage initial dans le noeud, et quand
je dois faire grandir, je double la taille de la table ; trouver
la place dans la nouvelle table va alors très vite.
Quand j'ai inventé l'utilisation des primes de Mersenne, je
travaillais sur un 8086. Et le compilateur ne savait pas
convertir les multiplications par une constante en des décalages
et des additions ou des soustractions. Là, il y avait
effectivement une différence de temps d'une facteur d'à peu près
cinq.
J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
En général, on fait le calcul modulo 2^N, ou N est le nombre de
bits de la machine, ce qui veut dire que le modulo est gratuit.
Seulement une fois calculer sur la chaîne complète, on fait
modulo la taille de la table. Ça limite les dégats.
Mais en fait, j'utilise aussi systèmatiquement des tables de
taille 2^n, simplement parce que c'est plus facile à les faire
grandir -- je garde le hachage initial dans le noeud, et quand
je dois faire grandir, je double la taille de la table ; trouver
la place dans la nouvelle table va alors très vite.
Quand j'ai inventé l'utilisation des primes de Mersenne, je
travaillais sur un 8086. Et le compilateur ne savait pas
convertir les multiplications par une constante en des décalages
et des additions ou des soustractions. Là, il y avait
effectivement une différence de temps d'une facteur d'à peu près
cinq.J'ai relu il y a peu le bouquin de Sedgewick (algos en C) a
propos des fonctions de hachage et utiliser N (taille de la
table, i.e. nombre de noeuds de liste primaires) premier avec
une simple méthode additive modulo N (méthode de Horner)
semble être ce qu'il y a de mieux comme compromis
simplicité/efficacité.
taille de table premier est plus lent que prendre N = 2^M
(modulo = mask). Dans ce cas c'est la constante additive qui
doit etre premiere (pas plus cher).
En général, on fait le calcul modulo 2^N, ou N est le nombre de
bits de la machine, ce qui veut dire que le modulo est gratuit.
Seulement une fois calculer sur la chaîne complète, on fait
modulo la taille de la table. Ça limite les dégats.
Mais en fait, j'utilise aussi systèmatiquement des tables de
taille 2^n, simplement parce que c'est plus facile à les faire
grandir -- je garde le hachage initial dans le noeud, et quand
je dois faire grandir, je double la taille de la table ; trouver
la place dans la nouvelle table va alors très vite.