Que se passe-t-il dans les coulisses lorsque vous marquez une expression régulière comme une expression à compiler? En quoi cela compare-t-il / est-il différent d'une expression régulière mise en cache?
À l'aide de ces informations, comment déterminez-vous quand le coût du calcul est négligeable par rapport à l'augmentation des performances?
Réponses:
RegexOptions.Compiled
indique au moteur d'expression régulière de compiler l'expression d'expression régulière en IL à l'aide de la génération de code léger ( LCG ). Cette compilation se produit lors de la construction de l'objet et le ralentit fortement . À leur tour, les correspondances utilisant l'expression régulière sont plus rapides.Si vous ne spécifiez pas cet indicateur, votre expression régulière est considérée comme "interprétée".
Prenons cet exemple:
Il effectue 4 tests sur 3 expressions régulières différentes. Tout d'abord, il teste une seule correspondance unique (compilée vs non compilée). Ensuite, il teste les correspondances répétées qui réutilisent la même expression régulière.
Les résultats sur ma machine (compilés en version, pas de débogueur attaché)
1000 matchs simples (construire Regex, Match et disposer)
1,000,000 correspondances - réutilisation de l'objet Regex
Ces résultats montrent que les expressions régulières compilées peuvent être jusqu'à 60% plus rapides dans les cas où vous réutilisez l'
Regex
objet. Cependant, dans certains cas, la construction peut être plus lente de plus de 3 ordres de grandeur .Il montre également que la version x64 de .NET peut être 5 à 6 fois plus lente en ce qui concerne la compilation d'expressions régulières.
La recommandation serait d' utiliser la version compilée dans les cas où soit
Spanner en préparation, le cache Regex
Le moteur d'expressions régulières contient un cache LRU qui contient les 15 dernières expressions régulières qui ont été testées à l'aide des méthodes statiques de la
Regex
classe.Par exemple:
Regex.Replace
,Regex.Match
etc .. tous utiliser le cache Regex.La taille du cache peut être augmentée en définissant
Regex.CacheSize
. Il accepte les changements de taille à tout moment au cours du cycle de vie de votre application.Les nouvelles expressions régulières ne sont mises en cache que par les helpers statiques de la classe Regex. Si vous construisez vos objets, le cache est vérifié (pour une réutilisation et un transfert), cependant, l'expression régulière que vous construisez n'est pas ajoutée au cache .
Ce cache est un cache LRU trivial , il est implémenté à l'aide d'une simple double liste chaînée. Si vous l'augmentez à 5000 et utilisez 5000 appels différents sur les helpers statiques, chaque construction d'expression régulière analysera les 5000 entrées pour voir si elle a déjà été mise en cache. Il y a un verrou autour de la vérification, de sorte que la vérification peut diminuer le parallélisme et introduire un blocage de thread.
Le nombre est fixé assez bas pour vous protéger de cas comme celui-ci, bien que dans certains cas, vous n'ayez pas d'autre choix que de l'augmenter.
Ma forte recommandation serait de ne jamais passer l'
RegexOptions.Compiled
option à un assistant statique.Par exemple:
La raison en est que vous risquez fortement de manquer le cache LRU, ce qui déclenchera une compilation très coûteuse . De plus, vous n'avez aucune idée de ce que font les bibliothèques dont vous dépendez, vous avez donc peu de capacité à contrôler ou à prédire la meilleure taille possible du cache.
Voir aussi: Blog de l'équipe BCL
Remarque : ceci est pertinent pour .NET 2.0 et .NET 4.0. Certains changements attendus dans la version 4.5 pourraient entraîner une révision de ce dernier.
la source
Compiled
dans le code de site Web où je stocke en fait un objet statique (à l'échelle de l'application)Regex
. Donc, leRegex
seul doit être construit une fois lorsque IIS démarre l'application, puis est réutilisé des milliers de fois. Cela fonctionne bien tant que l'application ne redémarre pas fréquemment.Cette entrée dans le blog de l'équipe BCL donne un bel aperçu: " Performances des expressions régulières ".
En bref, il existe trois types de regex (chacun s'exécutant plus rapidement que le précédent):
interprété
rapide à créer à la volée, lent à exécuter
compilé (celui que vous semblez demander)
plus lent à créer à la volée, rapide à exécuter (bon pour une exécution en boucle)
pré-compilé
créer au moment de la compilation de votre application (pas de pénalité de création au moment de l'exécution), rapide à exécuter
Donc, si vous avez l'intention d'exécuter l'expression régulière une seule fois, ou dans une section non critique pour les performances de votre application (c'est-à-dire la validation des entrées utilisateur), vous êtes d'accord avec l'option 1.
Si vous avez l'intention d'exécuter l'expression régulière en boucle (c'est-à-dire une analyse ligne par ligne du fichier), vous devriez choisir l'option 2.
Si vous avez de nombreuses expressions régulières qui ne changeront jamais pour votre application et sont utilisées intensément, vous pouvez choisir l'option 3.
la source
CompileModule
. Merde, j'ai besoin d'examiner plus en profondeur la nouvelle plate-forme.Il est à noter que les performances des expressions régulières depuis .NET 2.0 ont été améliorées avec un cache MRU d'expressions régulières non compilées. Le code de la bibliothèque Regex ne réinterprète plus la même expression régulière non compilée à chaque fois.
Il y a donc potentiellement une plus grande pénalité de performances avec une expression régulière compilée et à la volée. En plus des temps de chargement plus lents, le système utilise également plus de mémoire pour compiler l'expression régulière en opcodes.
Essentiellement, le conseil actuel est soit de ne pas compiler une expression régulière, soit de les compiler à l'avance dans un assembly distinct.
Réf: BCL Team Blog Performance d'expression régulière [David Gutierrez]
la source
1) Équipe de bibliothèque de classes de base sur regex compilée
2) Coding Horror, référencement n ° 1 avec quelques bons points sur les compromis
la source
J'espère que le code ci-dessous vous aidera à comprendre le concept des fonctions re.compile
la source