Le fait que la méthode replace renvoie un objet chaîne plutôt que de remplacer le contenu d'une chaîne donnée est un peu obtus (mais compréhensible quand on sait que les chaînes sont immuables en Java). Je prends un coup de performance majeur en utilisant un remplacement profondément imbriqué dans du code. Y a-t-il quelque chose que je puisse remplacer avec qui le rendrait plus rapide?Alternatives plus rapides pour remplacer la méthode dans une chaîne Java?
Répondre
C'est ce à quoi StringBuilder est destiné. Si vous allez faire beaucoup de manipulation, faites-le sur un StringBuilder
, puis transformez cela en String
quand vous en avez besoin.
StringBuilder
est décrit ainsi:
"Une séquence de caractères mutable Cette classe fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation".
Il a replace
(et append
, insert
, delete
, et al) et vous pouvez utiliser toString
pour se transformer en un véritable String
.
Rappelez-vous également d'utiliser StringBuilder si vous n'avez pas besoin de sécurité de thread, c'est généralement plus rapide et fonctionne de la même manière. –
En outre, StringBuilder.replace fonctionne très différemment de String.replace, vous ne pouvez donc pas l'utiliser comme remplacement direct! –
Toutes les manipulations de chaînes sont en général très lentes. Pensez à utiliser StringBuffer, ce n'est pas exactement comme la classe String, mais il a beaucoup en commun et il est également modifiable.
En général, si vous n'avez pas besoin que votre buffer soit thread-safe (c'est-à-dire que vous n'avez pas plusieurs threads manipulant le même buffer en même temps), vous devez utiliser StringBuilder au lieu de StringBuffer. – Avi
De la documentation de StringBuffer: La classe StringBuilder devrait généralement être utilisée de préférence à celle-ci, car elle supporte toutes les mêmes opérations mais elle est plus rapide car elle n'effectue aucune synchronisation. – tgamblin
Je travaillais beaucoup avec un environnement multi-thread, donc StringBuffer est venu naturellement dans mon esprit. –
Je suis d'accord avec ce qui précède. Utilisez StringBuffer pour la sécurité des threads et StringBuilder pour les threads simples.
Les messages précédents ont raison, StringBuilder/StringBuffer sont une solution. Mais, vous devez également vous demander si c'est une bonne idée de faire le remplacement sur les grandes chaînes en mémoire. J'ai souvent des manipulations de chaînes qui sont implémentées en tant que flux, donc au lieu de le remplacer dans la chaîne puis de l'envoyer à un OutputStream, je fais le remplacement au moment où j'envoie la chaîne au flux de sortie. Cela fonctionne beaucoup plus vite que tout remplacer.
Cela fonctionne beaucoup plus rapidement si vous souhaitez que ce remplacement implémente un mécanisme de modèle. Le streaming est toujours plus rapide car vous consommez moins de mémoire et si les clients sont lents, il vous suffit de générer à un rythme lent - donc il évolue beaucoup mieux.
Pouvez-vous donner un exemple? –
Si vous avez un certain nombre de chaînes à remplacer (telles que des séquences d'échappement XML), en particulier lorsque les remplacements sont de longueur différente du modèle, l'algorithme de type FSM lexer semble être le plus efficace. dans un flux, où la sortie est incrémentalement construite.
Peut-être qu'un objet Matcher pourrait être utilisé pour le faire efficacement.
Obtenez le char[]
du String
et parcourez-le. Utilisez un StringBuilder
temporaire.
Recherchez le motif que vous souhaitez remplacer pendant l'itération si vous ne trouvez pas le motif, écrivez les éléments que vous avez numérisés au StringBuilder
, sinon écrivez le texte de remplacement au StringBuilder
.
En ajoutant à la réponse @paxdiablo, voici un exemple d'implémentation d'un fichier replaceAll utilisant StringBuffers qui est ~ 3,7 fois plus rapide que String.replaceAll():
Code:
public static String replaceAll(final String str, final String searchChars, String replaceChars)
{
if ("".equals(str) || "".equals(searchChars) || searchChars.equals(replaceChars))
{
return str;
}
if (replaceChars == null)
{
replaceChars = "";
}
final int strLength = str.length();
final int searchCharsLength = searchChars.length();
StringBuilder buf = new StringBuilder(str);
boolean modified = false;
for (int i = 0; i < strLength; i++)
{
int start = buf.indexOf(searchChars, i);
if (start == -1)
{
if (i == 0)
{
return str;
}
return buf.toString();
}
buf = buf.replace(start, start + searchCharsLength, replaceChars);
modified = true;
}
if (!modified)
{
return str;
}
else
{
return buf.toString();
}
}
cas de test - la sortie est la suivante (Delta1 = 1917009502; Delta2 = 7241000026):
@Test
public void testReplaceAll()
{
String origStr = "1234567890-1234567890-";
String replacement1 = StringReplacer.replaceAll(origStr, "0", "a");
String expectedRep1 = "123456789a-123456789a-";
String replacement2 = StringReplacer.replaceAll(origStr, "0", "ab");
String expectedRep2 = "123456789ab-123456789ab-";
String replacement3 = StringReplacer.replaceAll(origStr, "0", "");
String expectedRep3 = "123456789-123456789-";
String replacement4 = StringReplacer.replaceAll(origStr, "012", "a");
String expectedRep4 = "1234567890-1234567890-";
String replacement5 = StringReplacer.replaceAll(origStr, "123", "ab");
String expectedRep5 = "ab4567890-ab4567890-";
String replacement6 = StringReplacer.replaceAll(origStr, "123", "abc");
String expectedRep6 = "abc4567890-abc4567890-";
String replacement7 = StringReplacer.replaceAll(origStr, "123", "abcdd");
String expectedRep7 = "abcdd4567890-abcdd4567890-";
String replacement8 = StringReplacer.replaceAll(origStr, "123", "");
String expectedRep8 = "4567890-4567890-";
String replacement9 = StringReplacer.replaceAll(origStr, "123", "");
String expectedRep9 = "4567890-4567890-";
assertEquals(replacement1, expectedRep1);
assertEquals(replacement2, expectedRep2);
assertEquals(replacement3, expectedRep3);
assertEquals(replacement4, expectedRep4);
assertEquals(replacement5, expectedRep5);
assertEquals(replacement6, expectedRep6);
assertEquals(replacement7, expectedRep7);
assertEquals(replacement8, expectedRep8);
assertEquals(replacement9, expectedRep9);
long start1 = System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = StringReplacer.replaceAll(origStr, "123", "abcdd");
}
long delta1 = System.nanoTime() -start1;
long start2= System.nanoTime();
for (long i = 0; i < 10000000L; i++)
{
String rep = origStr.replaceAll("123", "abcdd");
}
long delta2 = System.nanoTime() -start1;
assertTrue(delta1 < delta2);
System.out.printf("Delta1 = %d; Delta2 =%d", delta1, delta2);
}
Lorsque vous remplacez des caractères simples , considérez l'itération sur votre tableau de caractères mais remplacez les caractères en utilisant un (pré-créé) HashMap<Character, Character>()
.
J'utilise cette stratégie pour convertir une chaîne d'exposants entiers en caractères exposants unicode. Il est environ deux fois plus rapide que String.replace(char, char)
. Notez que l'heure associée à la création de la table de hachage n'est pas incluse dans cette comparaison.
Le code suivant est d'env. 30 fois plus rapide s'il n'y a pas de match et 5 fois plus vite s'il y a un match.
static String fastReplace(String str, String target, String replacement) {
int targetLength = target.length();
if(targetLength == 0) {
return str;
}
int idx2 = str.indexOf(target);
if(idx2 < 0) {
return str;
}
StringBuilder buffer = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2);
int idx1 = 0;
do {
buffer.append(str, idx1, idx2);
buffer.append(replacement);
idx1 = idx2 + targetLength;
idx2 = str.indexOf(target, idx1);
} while(idx2 > 0);
buffer.append(str, idx1, str.length());
return buffer.toString();
}
- 1. plus rapide pour remplacer la chaîne dans un modèle
- 2. Comment remplacer une méthode java de groovy
- 3. La méthode la plus efficace pour ... Chaîne aléatoire unique
- 4. Comment remplacer un caractère plus en utilisant la méthode String.replaceAll de Java
- 5. Regex pour remplacer la chaîne
- 6. Comment remplacer une méthode?
- 7. Méthode la plus optimale pour analyser la chaîne querystring au sein d'une chaîne en C#
- 8. Strip/remplacer les espaces dans une chaîne
- 9. remplacer les caractères dans un fichier (méthode plus rapide)
- 10. Quelle est la méthode canonique pour couper une chaîne dans Ruby sans créer une nouvelle chaîne?
- 11. chaîne remplacer la fonction
- 12. Remplacer plusieurs caractères dans une chaîne (XSLT)
- 13. Existe-t-il des alternatives à la méthode replaceAdjacentText d'IE?
- 14. Regex pour remplacer la chaîne avec une autre chaîne dans MS Word?
- 15. Comment remplacer � dans une chaîne
- 16. alternatives .net pour les programmes Java disponibles
- 17. Pourquoi deux threads Java (dans certains cas) sont-ils deux fois plus rapides qu'un?
- 18. Comment remplacer une méthode dans la classe dojox _Scroller?
- 19. Comment remplacer une variable dans une chaîne avec PHP?
- 20. Remplacer la chaîne dans le tableau javascript
- 21. itérateur pour remplacer les membres de la liste en Java?
- 22. Meilleure implémentation pour une méthode isNumber (chaîne)
- 23. Méthode la plus efficace pour surveiller une file d'attente
- 24. Est-ce que j'ai une méthode pour remplacer les propriétés système en Java?
- 25. au lieu de citations des barres obliques dans la chaîne JavaScript remplacer la méthode
- 26. Chaîne MySQL remplacer
- 27. MappedSuperclass Alternatives dans Grails
- 28. Java: paramètre Enum dans la méthode
- 29. Remplacer «\» par «/» dans une chaîne App C# WinForm
- 30. remplacement regex dans la chaîne java
heh heh remplacer remplacer – ojblass
Vous utilisez des chaînes? êtes-vous fou? utilisez un tableau d'octets! – IAdapter