OK
AJAX error!

Les forumsGrammalectePetit bug dans dawg.js

Petit bug dans dawg.js

Bonjour,

J'essaie de continuer mon portage de graphspell vers rust et je me suis aperçu qu'il y avait un potentiel bug (dans certains cas ça donne un mauvais résultat).

Cette partie :


// chars
for (let c of sFlex) {
if (!dChar.get(c)) {
dChar.set(c, nChar);
lChar.push(c);
nChar += 1;
}
dCharOccur.set(c, dCharOccur.gl_get(c, 0) + 1);
}
// affixes to find stem from flexion
let sAff = funcStemmingGen(sFlex, sStem);
if (!dAff.get(sAff)) {
dAff.set(sAff, nAff);
lAff.push(sAff);
nAff += 1;
}
dAffOccur.set(sAff, dAffOccur.gl_get(sAff, 0) + 1);
// tags
if (!dTag.get(sTag)) {
dTag.set(sTag, nTag);
lTag.push(sTag);
nTag += 1;
}


Devrais plutôt être comme ceci (les if (!XXX.get(c)) { remplacer en if (!XXX.has(c)) {):


// chars
for (let c of sFlex) {
if (!dChar.has(c)) {
dChar.set(c, nChar);
lChar.push(c);
nChar += 1;
}
dCharOccur.set(c, dCharOccur.gl_get(c, 0) + 1);
}
// affixes to find stem from flexion
let sAff = funcStemmingGen(sFlex, sStem);
if (!dAff.has(sAff)) {
dAff.set(sAff, nAff);
lAff.push(sAff);
nAff += 1;
}
dAffOccur.set(sAff, dAffOccur.gl_get(sAff, 0) + 1);
// tags
if (!dTag.has(sTag)) {
dTag.set(sTag, nTag);
lTag.push(sTag);
nTag += 1;
}



Cordialement,
Sébastien
le 14 novembre 2020 à 14:14
Bonjour,

Oui, merci. C’est corrigé.
le 14 novembre 2020 à 14:56
Un autre plus gênant :


__str__ () {
// Caution! this function is used for hashing and comparison!
let sFinalChar = (self.final) ? "1" : "0";
let l = [sFinalChar];
for (let [key, node] of this.arcs.entries()) {
l.push(key.toString());
l.push(node.i.toString());
}
return l.join("_");
}


Devrait être : (le problème viens sans doute du code de la conversion de python ;) : (le self est un this)


__str__ () {
// Caution! this function is used for hashing and comparison!
let sFinalChar = (this.final) ? "1" : "0";
let l = [sFinalChar];
for (let [key, node] of this.arcs.entries()) {
l.push(key.toString());
l.push(node.i.toString());
}
return l.join("_");
}



Il m'a fait perdre quelques heures vu que mon code donnait pas les même résultats lol
Je comprend pourquoi tu ne veux pas trop toucher a cette partie c'est une vrai prise de tête lol
le 15 novembre 2020 à 10:25
Oui, merci. En effet, c’est un bug qui me fait m’interroger sur le fait qu’on ne l’ait pas vu plus tôt. Il est vrai qu’il ne concerne que les dictionnaires personnels faits avec Firefox/Thunderbird, mais je m’interroge, parce que je n’ai pas constaté de dysfonctionnement à l’usage.
(Tous les dictionnaires incorporés avec les extensions sont faits avec la version Python.)

Il est certain que ce n’est pas la partie du code la plus facile, c’est l’une des plus complexes, d’autant plus que ce code fut conçu à une époque où j’avais fait beaucoup de tests de toutes sortes. C’est une zone expérimentale que je n’ai jamais pris la peine de nettoyer pendant longtemps, jusqu’à dernièrement où j’ai effacé beaucoup de code qui ne servait à rien. La révision n’est d’ailleurs pas encore terminée, mais ça viendra en son temps.
le 15 novembre 2020 à 11:03
Il me semble qu'il y avait eut dans le passé des topiques qui disaient que certains avaient des problème avec les dictionnaires perso.

Je pense que c'était de la chance que ça fonctionnait dans pas mal de cas ça arrive mdr J'ai mis du temps a comprendre d'où venait le fait que je ne retrouvais pas les même index dans certains cas ;)

C'est sure cette partie contiens beaucoup de code mort ou parfois des fonctions qui ne font rien d'autre qu'appeler une autre fonction du genre


finish () {
// minimize unchecked nodes
this._minimize(0);
}


autant appeler directement this._minimize(0); a la place de finish() ;) mais bon c'est pas trop gênant c'est juste la lisibilité du code ;)
le 15 novembre 2020 à 12:02
S’il y a un optimiseur qui se charge de simplifier ce type d’appel ça ne change effectivement rien (enfin une fois que l’optimiseur est passé).

En revanche, j’ai fait, sur mon ordi avec le CPU cadencé à 1.7GHz, quelques tests rapides avec un langage qui est réellement compilé (ce qui n’est le cas ni de Python, ni de java (script ou pas d’ailleurs)) mais qui ne fait pas ce genre d’optimisation du code et je trouve, les différences suivantes :
+12 cycles CPU de plus par appels en utilisant une structure de type « objet ».
+3 cycles CPU de plus par appels en utilisant que des fonctions.

La différence trouvée n’est certes pas énorme. Mais si le code concerné se trouve dans une boucle qui est dans une boucle qui est dans une boucle qui est… Bah au final ça peut faire une différence, surtout si le traitement réalisé est rapide à exécuter.
le 15 novembre 2020 à 21:22
Encore un, comme on dit jamais deux sans trois ;)

Dans la class DawgNode


sortArcs (dValOccur) {
let lTemp = Array.from(this.arcs.entries());
lTemp.sort(function (a, b) {
if (dValOccur.get(a[0], 0) > dValOccur.get(b[0], 0))
return -1;
if (dValOccur.get(a[0], 0) < dValOccur.get(b[0], 0))
return 1;
return 0;
});
this.arcs = new Map(lTemp);
}


A remplacer par ;) =>


sortArcs (dValOccur) {
let lTemp = Array.from(this.arcs.entries());
lTemp.sort(function (a, b) {
if (dValOccur.get(a[0]) > dValOccur.get(b[0]))
return -1;
if (dValOccur.get(a[0]) < dValOccur.get(b[0]))
return 1;
return 0;
});
this.arcs = new Map(lTemp);
}


En javascript le map.get n'a qu'un argument... Et ici c'est inutile d'utilisé la fonction perso gl_get
le 16 novembre 2020 à 02:02
@IllusionPerdu : Oui, il y avait eu des problèmes concernant les dictionnaires auparavant, mais rien qui concerne ces cas.
J’ai regardé le code qui permet de comprendre pourquoi ça fonctionnait quand même contre toute attente : c’est bien simple, l’effet de bord est léger et n’est pas perceptible pour les utilisateurs. Le dictionnaire fonctionnait la plupart du temps normalement, parce la confusion entre self et this n’engendrait qu’une erreur de représentation des nodes et non pas une erreur de constitution des nodes. Autrement dit, le graphe était bien formé, mais il n’était pas toujours bien compressé. Parfois un node final n’était pas vu comme node final, parce l’information disparaissait au moment de la compression. A priori, ce devait arriver rarement, mais c’est difficile à estimer. C’est vraiment un bug subtil. Merci de l’avoir signalé.

@Naheulf: ce code n’est exécuté qu’une seule fois, à la fin de la création d’un dictionnaire. Ça n’a donc aucune incidence de performance.

@IllusionPerdu : Oui, en effet. Le problème vient du fait que j’écris toujours le code en Python et qu’ensuite je le convertis en JS. Ici, ça n’a aucune incidence, JS ignore les paramètres surnuméraires. C’est corrigé.
le 16 novembre 2020 à 11:35
Autant l'indirection signaler au #5 n'est appelée qu'une fois mais


__hash__ () {
// Used as a key in a python dictionary.
return this.__str__();
}


est appelé un certain nombre de fois ;)


J'ai préféré le signaler car on ne sais jamais si dans une futur version le get prend 2 arguments et que le 2ème argument par exemple transforme le résultat du get ;) (on ne sais jamais)

Il n'y a pas de soucis je découvre les petits problèmes grâce au fort typage du Rust.
le 16 novembre 2020 à 12:18
@Admin est-ce qu'il y a une raison particulière d'utilisé encore le dictionnaire binaire et non de généré lByDic directement ?

C'est assez simple de s'en passé de cette conversion intermédiaire... Si tu veux, je peux te le faire assez rapidement ;)
le 17 novembre 2020 à 01:50
Oui, la raison, c’est que je ne suis pas sûr de vouloir abandonner définitivement tout format binaire. Je me suis laissé le temps d’y penser, voire de changer d’avis, même si c’est peu probable.
le 17 novembre 2020 à 09:27
Juste pour info voici un diff pour viré l'étape intermédiaire création de la chaine binaire :
git.gravier.pro…

Un petit nettoyage de code mort a été fait au passage ;) J'ai laissé la possibilité de la création du dictionnaire binaire.

[EDITED] Oups je m'était planter de fichier ;)

[EDITED NOTE] J'ai fini la conversion de dawg en rust binaire pour créer un dictionnaire json à partir du lex il suffit de 12s c'est beaucoup plus rapide que la version python.
le 17 novembre 2020 à 18:05
Merci. Je vais bientôt publier une nouvelle version.
Dès que ce sera fait, ce patch sera intégrable. Je préfère ne pas risquer d’intégrer un bug passé inaperçu.
le 28 novembre 2020 à 18:21

Notification par e-mail    0