Chaîne replaceAll() vs Comparateur de replaceAll() (différences de Performances)
Question assez simple, mais ce qui est à venir à partir d'un C/C++ personne d'entrer dans les subtilités de Java.
Je comprends que je peux tirer jusqu'à jUnit et un peu de tests de performance de mon propre pour obtenir une réponse; mais je me demande simplement si c'est là-bas.
Sont là connu différence(s) entre la Chaîne.replaceAll() et de la Correspondance.replaceAll() (Sur un Matcher Objet créé à partir d'une expression régulière.Motif) en termes de performance?
Aussi, quels sont les API de haut niveau 'ish différences entre les deux? (L'immuabilité, la Manipulation des valeurs Null, la Manipulation des chaînes vides, faire le café, etc.)
Vous devez vous connecter pour publier un commentaire.
Selon la documentation de
String.replaceAll
, il a à dire à propos de l'appel de la méthode:Par conséquent, il peut être prévu la performance entre l'invocation de la
String.replaceAll
, et de créer explicitement unCorrespondance
etMotif
devrait être le même.Modifier
Comme cela a été souligné dans les commentaires, la différence de performances étant inexistante serait vrai pour un seul appel à
replaceAll
deString
ouMatcher
, cependant, si l'on doit effectuer plusieurs appels àreplaceAll
, on pourrait s'attendre à être bénéfique pour tenir sur un compiléPattern
, donc relativement cher modèle d'expression régulière de compilation n'a pas à être exécuté à chaque fois.regex
Chaîne est statique, tout javac compilateurs assez intelligent pour comprendre que laPattern
objet peut être trop statique et de créer automatiquement un champ statique dans le bytecode généré? Sonne comme un excellent moyen d'améliorer les performances sur le code, tout en améliorant la lisibilité.Pattern.compile(...).matcher("ignored input")
, puis l'utiliser avectheMatcher.reset(theString).replaceAll(...)
Code Source de
String.replaceAll()
:Il a pour compiler le modèle de la première, si vous allez exécuter plusieurs fois avec le même motif sur les chaînes courtes, les performances seront bien meilleures si vous réutilisez un masque compilé.
La différence principale est que si vous vous tenez sur la
Pattern
utilisé pour produire de l'Matcher
, vous pouvez éviter de recompiler le regex chaque fois que vous l'utilisez. En passant parString
, vous n'aurez pas la capacité de "cache" de ce genre.Si vous avez un autre regex à chaque fois, à l'aide de la
String
de la classereplaceAll
est très bien. Si vous appliquez la même expression régulière pour de nombreuses chaînes, créer unPattern
et de le réutiliser.Immutabilité /thread de sécurité: compilé les Modèles sont immuables, les allumettes ne sont pas. (voir Est Java Regex "Thread-Safe"?)
La manipulation des chaînes vides: replaceAll doit gérer des chaînes vides gracieusement (qu'il ne correspond pas à une entrée vide, patron de la chaîne)
Faire le café, etc.: le dernier que j'ai entendu, ni Chaîne, ni Motif, ni Matcher avait toutes les fonctionnalités de l'API pour que.
edit: comme pour le traitement des valeurs nulles, la documentation de la Chaîne et le Modèle n'est pas explicitement de le dire, mais je soupçonne qu'ils jetterais un NullPointerException car ils attendent une Chaîne de caractères.
La mise en œuvre de
String.replaceAll
vous dit tout ce que vous devez savoir:(Et les docs disent la même chose.)
Alors que je n'ai pas vérifié pour la mise en cache, je serais certainement s'attendre à ce que la compilation d'un modèle une fois et de garder un point de référence fixe serait plus efficace que d'appeler
Pattern.compile
avec le même modèle à chaque fois. Si il y a un cache ça va être un petit efficacité de sauver, s'il n'y a pas, il pourrait être un grand.La différence est que Chaîne de caractères.replaceAll() compile les regex chaque fois qu'il appelle. Il n'y a pas d'équivalent .NET statique de la Regex.Méthode replace (), qui place automatiquement la compilation des regex. Généralement, replaceAll() est quelque chose que vous n'avez qu'une seule fois, mais si vous allez l'appeler à plusieurs reprises avec la même expression régulière, en particulier dans une boucle, vous devez créer un Modèle objet et utiliser le Comparateur de méthode.
Vous pouvez créer le Comparateur de venir de temps, trop, et d'utiliser la méthode reset() de reciblage pour chaque utilisation:
Les performances, les avantages de la réutilisation du Matcher, bien sûr, n'est nulle part aussi grande que celle de la réutilisation du Modèle.
Autres réponses suffisantes pour couvrir les performances de la partie de l'OP, mais une autre différence entre
Matcher::replaceAll
etString::replaceAll
est aussi une raison pour compiler votre proprePattern
. Lorsque vous compilez unPattern
vous-même, il y a des options comme des drapeaux pour modifier la façon dont l'expression régulière est appliquée. Par exemple:La
Matcher
s'appliquera à toutes les options que vous définissez lorsque vous appelezMatcher::replaceAll
.Il y a d'autres options que vous pouvez définir ainsi. Surtout, je voulais juste faire remarquer que le
Pattern
etMatcher
API a beaucoup d'options, et c'est la principale raison d'aller au-delà de la simpleString::replaceAll