26/02/2017, 21:15
(Modification du message : 27/02/2017, 01:52 par MenzAgitat.)
La documentation Tcl dit ceci :
En faisant ceci, on stocke "foobar" dans la variable $regexp sous forme de string :
comme on peut le voir ici :
mais dès qu'on exécute ceci, Tcl redéfinit la variable comme un Tcl_Obj contenant en plus de la string, une version précompilée :
comme on peut le voir ici :
(à noter que la commande ::tcl::unsupported::representation existe à partir de Tcl 8.6)
Démonstration de l'intérêt de stocker les patterns de regexp dans des variables afin de les pré-compiler et en accélérer l'exécution :
Sans pré-compilation :
Avec pré-compilation :
Le gain de temps d'exécution en stockant les expressions régulières dans des variables est considérable.
Une fois déclarées, ces variables ne devront plus être altérées sous peine de les reconvertir en strings simples. Il faudra donc éviter de les déclarer au début d'un procédure puisque chaque exécution de cette dernière écrasera les expressions pré-compilées.
Déclarez-les avec variable dans votre namespace eval ou avec global si vous n'utilisez pas de namespace (mais ça, c'est mal).
Citation :Tcl dynamically caches the compiled regular expressions. The Tcl core caches the last 30 REs it compiled but you can cause an number of RE's to be cached by assigning them to variables.
If a regular expression is assigned to a variable and the variable is not changed, the Tcl core will save the compiled version of the RE and use the precompiled version of the variable during next evaluation.
In the core the compiled version of the RE is stored in the Tcl_Obj, along with its string representation.
En faisant ceci, on stocke "foobar" dans la variable $regexp sous forme de string :
tcl
set regexp {foobar}
comme on peut le voir ici :
Citation :.tcl ::tcl::unsupported::representation $regexp
Tcl: value is a pure string with a refcount of 6, object pointer at 0x40514d0, string representation "foobar"
mais dès qu'on exécute ceci, Tcl redéfinit la variable comme un Tcl_Obj contenant en plus de la string, une version précompilée :
tcl
regexp $regexp foobar
comme on peut le voir ici :
Citation :.tcl ::tcl::unsupported::representation $regexp
Tcl: value is a regexp with a refcount of 7, object pointer at 0x40514d0, internal representation 0x40a7610:(nil), string representation "foobar"
(à noter que la commande ::tcl::unsupported::representation existe à partir de Tcl 8.6)
Démonstration de l'intérêt de stocker les patterns de regexp dans des variables afin de les pré-compiler et en accélérer l'exécution :
Sans pré-compilation :
tcl
.tcl time { for {set i 0} {$i < 40} {incr i} { regexp [concat {(f)(o{2,})(b|[cdefg])(ar|fg|df|tr|uk)} $i] foobar } } 100
Tcl: 11416.04 microseconds per iteration
Avec pré-compilation :
tcl
.tcl for {set i 0} {$i < 40} {incr i} { set regexp($i) [concat {(f)(o{2,})(b|[cdefg])(ar|fg|df|tr|uk)} $i] }
Tcl:
.tcl time { for {set i 0} {$i < 40} {incr i} { regexp $regexp($i) foobar } } 100
Tcl: 312.0 microseconds per iteration
Le gain de temps d'exécution en stockant les expressions régulières dans des variables est considérable.
Une fois déclarées, ces variables ne devront plus être altérées sous peine de les reconvertir en strings simples. Il faudra donc éviter de les déclarer au début d'un procédure puisque chaque exécution de cette dernière écrasera les expressions pré-compilées.
Déclarez-les avec variable dans votre namespace eval ou avec global si vous n'utilisez pas de namespace (mais ça, c'est mal).