super le résultat du profilage. Dommage que ça ne marche pas chez moi.
je suis en accord complet avec ce qui a été dit plus haut (sauf la relecture du fichier 140M de fois, j’y reviendrai plus bas). C’est impressionnant comment une mauvaise utilisation des regex peut conduire à une aussi grande chute de performance. Ce qui m’a étonné le plus, c’est le temps perdu avec les regex :
(1) /^\s*\$EndNodeData\s*$/ et /^\s*\$NodeData\s*$/
alors que mon intuition me disait que la regex suivante était la plus compliquée, donc la plus pénalisante :
(2) /^\s*(\d+)\s+($format_reel)\s+($format_reel)\s+($format_reel)\s*$/
Certes, le cout de la regex (1) est seulement d’environ 500 ns par appel contre 2 micro s pour la (2). Mais la (1) est appelée tellement de fois que ça en devient le boulet principal. Bluffant. Le pire, c’est que j’utilise énormément ces tournures dans mes scripts :
1 2 3 4 5
| while(<>) {
last if(chaine de caracteres);
next if(not /^\s*(\d+)\s+($format_reel) etc
$/);
} |
ou bien encore ça pour me positionner à un endroit d’un fichier :
while(<>) {last if/chaine de caracteres/);}
alors que c’est vraiment se tirer une balle dans le pied.
Le next unless /noeud/ ainsi que l’utilisation de index comme proposé par Lolo78 me montre une nouvelle manière pour coder tout ça plus efficacement. Merci.
Philou67430 :
Concernant la lecture du fichier 140M de fois, j’ai effectivement constaté qu’une recherche par position $. stocké dans un hash était bien plus efficace que des regex (c’était l’objet de ma dernière modif, cf ma dernière pièce jointe, ce qui m’avait permis de passer de 4 mn à 2 mn 30 s en multi-threading). Je me demande si il n’y aurait pas moyen d’aller plus vite encore avec tell et seek.
Philou67430 :
Je ne sais pas si l'argument tient : si l'on parle bien du gros fichier $fgmsh_dpl, il est lu une première pour remplir le tableau @table_dpl_1, puis plusieurs fois pour renseigner des tableaux @liste_dpl_UX, @liste_dpl_UY et @liste_dpl_UZ, mais grosso modo, même si les tableaux @liste_dpl_U* ne contiennent que des sous-ensemble du tableau @table_dpl_1, ils semblent contenir les mêmes données.
Je ne stocke jamais la totalité du fichier d’entrée dans @table_dpl_1. Dans l’ETAPE 3, je ne stocke jamais plus d’un ‘’NodeData’’ du fichier d’entrée, c’est-à-dire l’état de mes noeuds à un seul temps donné… et le fichier contient 1644 NodeData!!
Néanmoins, cette relecture frénétique de ce fichier est un réel problème. Mais je me souviens pourquoi je n’avais pas le choix, car :
1. Compte-tenu de la structure du fichier d’entrée, je ne peux pas écrire directement le fichier final en traitant tous les noeuds à la fois => je dois donc traiter chaque noeud séparément
2. si je fais en une passe (en lisant une seule fois le fichier), je dois écrire les données pour chaque noeud dans des fichiers séparés (c’est de là qu’a émergé l’idée de plein de fichiers temporaires). Dans ma première mouture, j’ouvrais tous ces petits fichiers prêts pour l’écriture et je me suis heurté à la limite de handle. J’ai donc été obligé de renoncer. J’ai donc testé une stratégie d’ouverture pour ajout + fermeture de ces petits fichiers un grand nombre de fois, ce qui n’était pas efficace (à vue de nez car je n’avais pas de profilage pour me renseigner)
3. la solution 2. n’étant pas satisfaisante, je me suis lancé dans la version actuelle que je vous ai donné. La nécessité de relire plein de fois le fichier d’entrée s’est imposée et j’ai conservé (sans doute à tord) l’idée de plein de petits fichiers temporaires. Mais ce n’était plus utile dans le cadre d’une relecture pour chaque noeud.
4. la question de la création de plein de petits fichiers n’était pas un choix bien pensé dans le cadre de la solution 3., mais finalement, ça m’a permis de paralleliser. Tout est bien qui finit bien.
Merci à vous. J’ai maintenant pas mal d’infos pour mieux réécrire mon code. Avec en plus le multi-threading, j’espère que ça va carburer. Et dire que le sujet de ce topic était de ne pas réécrire de scripts…
N’hésitez pas à me faire part de votre expérience concernant tell et seek pour se positionner rapidement dans un fichier (efficace, pas efficace ??)
ps : désolé pour le pavé…
Partager