1

yop©,


J'aimerais faire un checksum sur deux octets de chaines de caractères contenant ces symboles : a-z, A-Z, 0-9, '_', '.'.

Le problème, c'est que additionner deux mots de même longueur me donnera des résultats proches, et sûrement plus de collisions que si j'additionnais les termes d'une string comprenant des caractères allant de 0 à 255.

Les collisions ne sont pas graves (sauf pour les perfs), les checksums sont justes destinés à accélérer la recherche d'une chaine dans une table de structures {short Checksum, char* Ptr}, sans à avoir à faire des strcmp sur chaque entrée (je code en 68k, et le gain en vitesse est très significatif).

Qui plus est, la somme des lettres d'une string, même "grande", ne dépassera jamais plus d'une douzaine de bits, sur les 16 disponibles dans le champ Checksum.
Ma méthode de checksum qui consiste à additionner juste les caractères des strings les uns aux autres me semble donc peu efficace.

Quel méthode me permettrait donc d'avoir un checksum bien plus efficace (ie plus de bits utilisés, moins de collisions) sans pour autant perdre trop en performance au moment du calcul du-dit checksum ?

2

3

J'ai eu le problème quand j'ai ajouté le type 'string' à mon moteur de base de donnée, construit ta chaine de la façon suivante :

2 octets : CRC16
2 octets : La taille de ta chaine
4 octets : Les 4 premiers caractères de ta chaine

Donc si tu places les 4 premiers octets en header de ta chaine, ta clé est composé des 8 octets suivants le header. Ton risque de collision devient quasiment nul (le CRC, la taille de la chaine est un critère discriminant supplémentaire, plus le début de la chaine)

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

4

Quelle mémoire Pen^2, merci beaucoup grin

Kochise : C'est sûrement performant, mais je n'ai pas 8 octets à sacrifier par chaine, complètement impossible, c'est deux et rien que 2. Merci quand même. Je vai voir ce qu'est un CRC, comment ça se calcule.

5

http://www.abcelectronique.com/forum/showthread.php?t=7301

Fait gaffe au risque de collision sur les chaines. Le CRC n'est fiable que sur les chaines de même taille

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

6

Folco (./1) :
yop©,


J'aimerais faire un checksum sur deux octets de chaines de caractères contenant ces symboles : a-z, A-Z, 0-9, '_', '.'.

Le problème, c'est que additionner deux mots de même longueur me donnera des résultats proches, et sûrement plus de collisions que si j'additionnais les termes d'une string comprenant des caractères allant de 0 à 255.

Les collisions ne sont pas graves (sauf pour les perfs), les checksums sont justes destinés à accélérer la recherche d'une chaine dans une table de structures {short Checksum, char* Ptr}, sans à avoir à faire des strcmp sur chaque entrée (je code en 68k, et le gain en vitesse est très significatif).

Qui plus est, la somme des lettres d'une string, même "grande", ne dépassera jamais plus d'une douzaine de bits, sur les 16 disponibles dans le champ Checksum.
Ma méthode de checksum qui consiste à additionner juste les caractères des strings les uns aux autres me semble donc peu efficace.

Quel méthode me permettrait donc d'avoir un checksum bien plus efficace (ie plus de bits utilisés, moins de collisions) sans pour autant perdre trop en performance au moment du calcul du-dit checksum ?



Tu viens d'inventer... le tableau de hashage (hash table) ^^

Si tu hash des octets sur une valeur calculé en 16bits, une rotation entre chaque nouvelles valeur permet un minimum d'effet d'avalanche sur le resultat final. Calculer un hash "correct" est proche de la crypto.

un exemple de CRC tout con: unsigned short crc(char *value, int size) { unsigned short crc = 0xDEAD; // toujours mettre une valeur d'initialisation for (i = 0; i < size; i++) { c = value[i] crc = c ^ (crc); crc = ((crc << 8) & 0xFF00) | ((crc >> 8) & 0xFF); crc += c; } return crc; }

Par contre se limiter a certain caractere n'a pas de sens, tout ce que tu vas faire, c'est de complexifier inutilement ton code, autant travailler sur un octet, tu gagneras en vitesse et en lisibilitée
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

7

Merci pour tout. Je vais utiliser une solution avec une simple rotation et un modulo tout con pour minimiser les collisions (que deux chaines avec les mêmes caractères dans deux ordres différents ne rentrent pas en collision) sans pour autant perdre en vitesse. Merci à tous. smile

8

Godzil : attention, comme je le disais à Folco, je suis pas sûr qu'un algo de CRC fasse un très bon algo de hashage (et vice-versa), même si à première vue ça a l'air ressemblant ; les algos "classiques" de hashage sont différents des algos de CRC.

En gros un algo de CRC est optimisé pour la détection des erreurs touchant des bits dispersés ou des "bursts", un algo de hashage est optimisé pour minimiser les collisions dans les cas usuels. Je pense pas qu'on puisse établir de correspondance directe entre ces deux critères.

Quant au lien avec la crypto (je me doute que tu le sais, mais je précise pour d'autres qui liraient le topic), l'effet d'avalanche est effectivement utilisé pour les deux, mais la crypto demande nettement plus : un algo pour lequel on sait générer des collisions artificiellement, c'est pas grave pour du hashage qui sert à accélérer des opérations, mais pour de la crypto c'est désastreux smile
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

9

Zerosquare: Oui, d'ailleurs, mais je n'ai pas le bouquin, mais j'ai un algo de hash adapté aux chaines, faut que je le retrouve.

Pour les tables de hashage, la collision est plutot géré au niveau de l'insertion, recherche dans le tableau que dans l'algo de hash

edit: Retrouvé ^^
/**************************************************************** * * * Fonction de hashage adapté de "Compilers : Principles, * * Techniques, and Tools, de Alfred V. AHO, Ravi SETHI, * * et Jeffrey D. ULLMAN, qui l'attribuent à P. J. WEINBERGER * * * ****************************************************************/ /**************************************************************** * * * --------------------------- hashpjw.c --------------------- * * * ****************************************************************/ #include "hashpjw.h" /**************************************************************** * * * ------------------------- hashpjw ------------------------- * * * ****************************************************************/ int hashpjw(const void *cle) { const char *ptr; int val; /************************************************************** * * * Hache la clé à l'aide d'opérations bit à bit. * * * *************************************************************/ val = 0; ptr = cle; while (*ptr != '\0') { int tmp; val = (val << 4) + (*ptr); if (tmp = (val & 0xf0000000)) { val = val ^ (tmp >> 24); val = val ^ tmp; } ptr++; } /************************************************************** * * * En pratique, on remplace PRIME_TBLSIZ * * par la taille réelle de la table. * * * *************************************************************/ /* Petit ajout (02/05/2002) on empeche le retour de toute valeur négative */ if ((val % PRIME_TBLSIZ) < 0) { return 0-(val % PRIME_TBLSIZ); } else { return val % PRIME_TBLSIZ; } }
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

10

Ah, c'est celle que tu avais donnée dans le topic montré par Pen^2 smile Les tests de vitesse la plaçaient un peu en dessous de celle de DJB optimisée par Pollux (fast and perfect hash cheeky) à cause des décalages de 4 et 24 bits, et l'homogénéité de la table semblait moins bonne.

Godzil et moi avions posté les codes sources de 2 programmes de tests, qui n'avaient pas tout à fait les mêmes objectifs. Tu pourrais les faire tourner pour faire ton choix en fonction de tes critères, Folco.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

11

moi elle me plait cette méthode, elle est courte et compacte.

12

(et pas longue !)

13

14

Pas longue et rapide, ça va pas plaire aux filles :/

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

15

En Erlang, ça devrait ralentir un peu, et puis la fin du nom devrait leur plaire #itm# dehors

16

avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

17

Je peux pas me décaler un décalage sur 24 bits, trop gourmand. Et autant swapper pour 24 bits amha.

18

Oh, c'était pas pour reprendre directement l'algo, mais pour les explications qui allaient avec hehe
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

19

Ah ok. Merci pour tout en tout cas, ça m'aide bien ! smile

20

Folco (./17) :
Je peux pas me décaler un décalage sur 24 bits, trop gourmand. Et autant swapper pour 24 bits amha.

Mauvaise habitude au passage, sur tous les processeurs "récents" (et même pas trop en fait) le décalage se fait sur un cycle, et parfois il est même chaîné à une opération. Par exemple sur ARM ceci prend un cycle:
add r1, r2, r3, lsl #12 // r1 = r2 + (r3<<12)
Fais gaffe que ce genre de chose ne te bloque pas quand tu conçois un algo rapide wink
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

21

(t'inquiètes, j'ai expliqué à Folco ce qu'était un barrel shifter l'autre jour, il en a été tout émoustillé cheeky)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

22

(quand on cherche à concevoir un *algo* rapide, on se fout totalement de ce qui est supporté ou non dans l'assembleur cible ^^)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

23

Euh, non, pas toujours... À haut niveau OK, mais dès que c'est du traitement de données massif, on ne s'en fout pas (par exemple sur PC, si tu veux que le compilo optimise tes opérations flottantes, vaut mieux comprendre comment marche le SSE. Et sur les systèmes "light" comme la TI, c'est encore plus vrai.)
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

24

Je pense aussi. Un algo, tout bien pensé qu'il sera, ne sera pas rapide s'il est mal implémenté. Et sachant que j'implémente sur TI, faut que je tienne compte de son proc.

25

./23 : justement, sur Ti il y a eu des fanatiques de l' "optimisation" à grand coups de remplacements d'instruction pour gagner 2 cycles, voire déroulage de boucle, et finalement ça n'a souvent pas le même ordre de grandeur d'efficacité que de repenser le problème autrement
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

Nostub powaaaaa ! Quoi, j'ai encore dit une connerie ?

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

27

Généralement quand on parle d'optimiser un algo on cherche plutôt à gagner un ordre de complexité sur un des processus, pas d'inverser deux opérations parce que le processeur peut les stager. Maintenant dans le cas de Folco où le meilleur algo est déjà connu, alors la seule différence peut se faire au niveau de l'implémentation.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

28

./25 : je sais bien qu'il vaut mieux commencer par optimiser l'algo avant d'optimiser l'implémentation, mais faut pas non plus ne jurer que par les O(machin). Beaucoup ont tendance à oublier que ça n'indique qu'une limite quand n tend vers l'infini, et que c'est défini à une constante multiplicative près. En pratique, un algo en O(n) avec une division à chaque itération peut très bien être plus lent qu'un algo en O(n²) qui n'en a pas, par exemple (pour des valeurs de n représentant les cas réels).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

29

Boaf, le plus simple est encore :

int nMaxString = N;
char **pStringArray = {"String1", "String2", "String3", ..., "StringN"};
char* pMyString = pStringArray[rand()%nMaxString];


C'est rapide, efficace, et t'évites les collisions. Par contre pour la prédictibilité...

Kochise
avatar
Si Dieu m'a de nouveau fait homme, cette fois il m'a pas raté : marcher sur l'eau et dupliquer les pains, ça marche p'us :/

30

./28 : oui oui, mais je ne parlais pas nécessairement de différence de niveaux de complexité (c'est effectivement pas ce qu'il y a de plus pertinent ici), à complexité "mathématique" égales il y a souvent une grosse marge à travailler avant que s'intéresser au cycles ne commence à être la meilleure solution.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)