Merci.
Je ne comprends pas bien ce que tu décris : comme tous les scripts
Perl, le programme est compilé à la volé et c'est à ce moment-là que
les .mo sont liés dans le programme...
Techniquement parlant, ça doit être un peu plus coûteux mais sans
plus...
PK
--
|\ _,,,---,,_ Patrice KARATCHENTZEFF
ZZZzz /,`.-'`' -. ;-;;,_ mailto:p.karatc...@free.fr
|,4- ) )-,_. ,\ ( `'-' http://p.karatchentzeff.free.fr
'---''(_/--' `-'\_)
En fait c'est le "un peu plus" que je voudrais évaluer.
Des tests de performances ont déjà été faits sur le produit sur lequel je
travaille et celui ci est assez verbeux, ça pourrait remettre certaines
clauses en cause.
Du coup lorsque je considère les milliers de lignes du genre ->
gettex("'Voulez-vous vraiment supprimer le fichier ressource du repertoire
...etc.'");
je pense que le temps de réponse doit forcemment être plus long que de
simples ->
gettex(3980);
Mais peut être me trompe-je ?
Je souhaite donc juste être détrompé :-)
C'est essentiellement une table de hashage de correspondance entre texte VO
et texte traduit.
> En fait après avoir fait le travail d'extraction, je m'inquiète un peu de
> voir des chaines interminables passées en paramètres et je me demande
> comment cela ne pourrait pas nuire aux performances du script.
Tout simplement parce que ce n'est pas sur le chemin critique. On traduit
avec l'architecture gettext les messages issus du programme et de ses
bibliothèques, pas les données que le programme manipule. Si le programme
travaille beaucoup, ça représente normalement une proportion négligeable de
ce qu'il fait.
On peut voir ça autrement : normalement, ce qui est traduit est destiné
directement à l'utilisateur, jamais à un traitement automatisé. Dans ce cas,
il va falloir l'afficher, ce texte. Ce qui veut dire qu'après être passé
dans gettext, il va probablement devoir passer dans Fretype et le serveur
X11. À côté, gettext, c'est négligeable.
Ok merci, c'est l' explication que j'attendais (celle qui rend confiant ;-).
Les tests de performance vont être rejoués je verrais à ce moment
concrètement la latence induite.
Oui.
La recherche se fait dans une table de hachage : le temps de réponse
est indépendant da la taille de la clé (sauf la première fois qu'on
voit cette clé).
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
Ok
Je pinaille mais sachant qu'une bonne partie de l'internationalisation porte
sur des services web, et que la traduction sera faite à chaque requête au
serveur, est ce que la méthode reste indiquée dans ce cas précis ?
Euh, allô ? Pour faire marcher une table de hachage, il faut une fonction de
hachage. Et une fonction de hachage qui ne lit pas la totalité de la clef
(donc temps au moins proportionnel à la longueur), c'est franchement pas
terrible.
>En fait c'est le "un peu plus" que je voudrais évaluer.
>Des tests de performances ont déjà été faits sur le produit sur lequel je
>travaille et celui ci est assez verbeux, ça pourrait remettre certaines
>clauses en cause.
>Du coup lorsque je considère les milliers de lignes du genre ->
>gettex("'Voulez-vous vraiment supprimer le fichier ressource du repertoire
>...etc.'");
>je pense que le temps de réponse doit forcemment être plus long que de
>simples ->
>gettex(3980);
Pas forcement extremement plus long.
Si ca commence a devenir genant, il y a sans doute moyen de bricoler un
pre-compilo en utilisant B (pour une fois que ca servirait a quelque chose).
Faudrait demander aux gens de Mason ce qu'ils en pensent... apres tout,
cote efficacite et cache de composants, ca fonctionne quand meme du feu de
dieu.
Oui, allo ! As-tu lu ce que j'ai dit ? La première fois qu'on lit la
clé, la fonction de hachage est appliquée (là, c'est proportionnelle à
la taille de la clé). Ensuite, le temps de réponse lors de l'accès aux
valeurs associées à cette clé est indépendant puisque le résultat de
la fonction de hachage est stocké.
Si vous ré-exécutez le script à chaqe fois (CGI classique), oui ! Tout
est recompilé à chaque requête.
Mais si vous en êtes à grapiller ce genre de pouillièmes, passez en
FCGI ou en mod_perl et vous n'aurez plus ce souci.
Stocké ? Stocké où ? gettext, ça prend un const char * en argument, il n'y a
pas de champ mutable où stocker le résultat de la fonction de hachage.
'const char *' ? En Perl ?
gettext, c'est une API C, à la base. Tu peux avoir un wrapper en perl
autour, mais je doute qu'il ajoute ce genre de cache.
Je complète ma réponse en vous conseillant de regarder du côté du
module Locale::Maketext qui pallie à plusieurs des défauts de la
philosophie 'gettext'.
En lisant la description de Gettext (que je n'utilise pas) :
Gettext.pm emulates the gettext library routines in Perl, although
it calls the external utility program gettext to actually read .mo
files.
j'en avais conclu que tout était réécrit en Perl (sauf la lecture des
fichiers .mo eux-mêmes) et donc avec des tables de hachages.
Mais ton message m'a fait douté. J'ai donc été lire le code. Et là...
Horreur ! On trouve des lignes du genre :
return `LC_MESSAGES=$oldlocale;$gettextcmd $self->{'DOMAINNAMÉ} $msgid`;
(J'ai un peu simplifié la commande).
Tu as donc raison sur les performances et c'est même bien pire
puisqu'il y a appel à un shell et à gettext (donc deux processus) à
chaque fois. Là, la longueur de la chaine ne pose plus de problème.
C'est *lent* quoi qu'on fasse ! (il faut dire que c'est une version
0.01)
Il existe aussi un module Locale::gettext (1.05) qui semble mieux
développé mais qui fait encore appel aux fonctions externes sans
utiliser la puissance de Perl.
Reste donc le module que de nombreuses personnes conseillent avec
raison : Locale::Maketext et sa variante Locale::Maketext::Gettext.
Merci
avant que je ne penche sur Locale::Maketext -> le principe est il le même
(dictionnaires portables compilés) ?
Sinon de manière générale les diverses remarques de ce thread m' en amènent
d'autres :
FCGI -> le programme sur lequel je travaille est multi plateforme mais
actuellement les tests sont sous IIS / perlis
lacunes de gettext -> en matière d'optimisation, je ne vois pas comment
aller "au delà" d'une hashtable (à partir du moment où l'index numérique est
proscrit) peu importe qu'on soit en pure perl ou pas.
+ une question sur le problème d'interpolation -> Est ce qu'il ya un moyen
de recenser les chaînes contenant des variables ("Le fichier nommé
$le_nom_du_fichier est ouvert.") plus élégant qu' un sprintf ou un
découpage ?
Non : les fichiers de traductions ne sont pas "compilés". Ils sont
implicitement compilés en mémoire à chaque lancement du script.
> Sinon de manière générale les diverses remarques de ce thread m' en amènent
> d'autres :
> FCGI -> le programme sur lequel je travaille est multi plateforme mais
> actuellement les tests sont sous IIS / perlis
Je n'ai jamais testé FastCGI avec IIS/Windows. Mais ça doit être
faisable puisqu'il existe un package Perl FCGI::IIS...
> lacunes de gettext -> en matière d'optimisation, je ne vois pas comment
> aller "au delà" d'une hashtable (à partir du moment où l'index numérique est
> proscrit) peu importe qu'on soit en pure perl ou pas.
L'optimisation a un prix : la mémoire.
Sinon, les améliorations apportées par Locale::Maketext sont plus sur
les aspects linguistiques. Il faut lire l'article qui explique tout
ça :
<http://search.cpan.org/dist/Locale-Maketext/lib/Locale/Maketext/TPJ13.pod>
> + une question sur le problème d'interpolation -> Est ce qu'il ya un moyen
> de recenser les chaînes contenant des variables ("Le fichier nommé
> $le_nom_du_fichier est ouvert.") plus élégant qu' un sprintf ou un
> découpage ?
Je ne comprends pas la question...
Ce n'est pas vraiment capital mais c'est le problème posé par le présence
des paramètres.
Dans l'option gettext on ne peut pas employer ce genre de construction :
print gettext("Le fichier : $nom_fichier est ouvert.\n");
On est obligé de faire soit ceci :
print gettext("Le fichier :"). $nom_fichier .gettext("est ouvert").".\n";
Soit ceci :
print sprintf (gettext("Le fichier : %s est ouvert.\n"), $nom_fichier);
Ce qui n'est pas tres pratique lorsqu'on est en phase d'extraction des
chaines.
Donc s'il ya une autre méthode je suis preneur.
Merci pour les conseils.
C'est un peu la même chose dans Locale::MakeText. Mais la syntaxe est
différente :
print maketext("Le fichier : [_1] est ouvert.\n"), $nom_fichier);
Ça permet de changer l'ordre d'apparition, de prévoir une éventuelle
fonction de traitement pour les cas compliqués, ça permet aussi de
vérifier qu'on n'oublie aucun argument...
Mais ça ne résoud pas votre problème : il faut quand même explorer
tout le code pour extraire les chaînes à traduire. En fait, c'est
assez fastidieux. Et c'est en général à ce moment-là qu'on se dit que
la prochaine fois, on prévoira de faire l'I18N dès de le départ ! ;-)
[...]
> Dans l'option gettext on ne peut pas employer ce genre de construction :
> print gettext("Le fichier : $nom_fichier est ouvert.\n");
> On est obligé de faire soit ceci :
> print gettext("Le fichier :"). $nom_fichier .gettext("est ouvert").".\n";
> Soit ceci :
> print sprintf (gettext("Le fichier : %s est ouvert.\n"), $nom_fichier);
<HS>
La première solution n'est évidemment pas recommandable. La forme du
langage étant spécifique à chaque langue, il faut laisser le maximum
de libertés aux traducteurs pour remettre les mots à leur place.
</HS>
Oui.
La deuxieme pose aussi ses problèmes comme le suggérait Paul Gaborit, selon
les langues
l'ordonnancement des attributs ou des verbes est différent.
Ok ça va, ça fait une semaine que je peaufine mes outils.
>En fait, c'est
> assez fastidieux. Et c'est en général à ce moment-là qu'on se dit que
> la prochaine fois, on prévoira de faire l'I18N dès de le départ ! ;-)
Oui enfin, si on est à l'origine du chantier :-)
[...]
> La deuxieme pose aussi ses problèmes comme le suggérait Paul
> Gaborit, selon les langues l'ordonnancement des attributs ou des
> verbes est différent.
L'ordonnancement n'est pas tant un problème que la gestion des
pluriels par exemple (prendre le polonais).