El hecho de que el método replace devuelva un objeto de cadena en lugar de reemplazar el contenido de una cadena dada es un poco obtuso (pero comprensible cuando se sabe que las cadenas son inmutables en Java). Estoy teniendo un gran golpe de rendimiento mediante el uso de un reemplazo profundamente anidado en algún código. ¿Hay algo con lo que pueda reemplazarlo que lo haga más rápido?Alternativas más rápidas para reemplazar el método en Java String?
Respuesta
Esto es para lo que StringBuilder se destina. Si va a hacer mucha manipulación, hágalo en un StringBuilder
, luego conviértalo en un String
siempre que lo necesite.
StringBuilder
se describe así:
"Una secuencia mutable de caracteres Esta clase proporciona una API compatible con StringBuffer, pero sin ninguna garantía de sincronización".
Tiene replace
(y append
, insert
, delete
, et al) y se puede utilizar toString
de transformarse en un verdadero String
.
Recuerde también utilizar StringBuilder si no requiere seguridad de subprocesos, generalmente es más rápido y funciona de la misma manera. –
Además, StringBuilder.replace funciona de manera bastante diferente a String.replace, por lo que no puede usarlo como reemplazo de reemplazo. –
Toda la manipulación de cadenas en general es muy lenta. Considere usar StringBuffer, no es exactamente como la clase String, pero tiene mucho en común y también es mutable.
En general, si no necesita que su búfer sea seguro para subprocesos (es decir, no tiene varios subprocesos que manipulen el mismo búfer a la vez), debe usar StringBuilder en lugar de StringBuffer. – Avi
De la documentación de StringBuffer: La clase StringBuilder generalmente se debe utilizar con preferencia a esta, ya que admite todas las mismas operaciones pero es más rápida, ya que no realiza ninguna sincronización. – tgamblin
Solía trabajar mucho con el entorno de subprocesos múltiples, así que StringBuffer vino a mi mente de forma natural. –
Estoy de acuerdo con lo anterior. Use StringBuffer para seguridad de hilos y StringBuilder cuando trabaje con hilos sueltos.
Las publicaciones anteriores son correctas, StringBuilder/StringBuffer son una solución.
Pero, también debe preguntarse si es una buena idea reemplazar las cadenas grandes en la memoria.
A menudo tengo manipulaciones de cadena que se implementan como una secuencia, por lo que en lugar de reemplazarlo en la cadena y luego enviarlo a un OutputStream, lo hago en el momento en que envío el String a la salida de salida. Eso funciona mucho más rápido que cualquier reemplazo.
Esto funciona mucho más rápido si desea que este reemplazo implemente un mecanismo de plantilla. La transmisión siempre es más rápida ya que consume menos memoria y si los clientes son lentos, solo necesita generar a un ritmo lento, por lo que escalará mucho mejor.
¿Puedes dar un ejemplo? –
Si tiene que reemplazar varias cadenas (como secuencias de escape XML), especialmente cuando las sustituciones son de diferente longitud que el patrón, el algoritmo tipo FSM lexer parece ser más eficiente, similar a la sugerencia de procesamiento en forma de flujo, donde la salida se construye incrementalmente.
Quizás un objeto Matcher se podría usar para hacerlo de manera eficiente.
Simplemente obtenga el char[]
del String
y repítalo. Use un StringBuilder
temporal.
Busque el patrón que desea reemplazar mientras itera si no encuentra el patrón, escriba las cosas escaneadas en StringBuilder
, escriba el texto de reemplazo en StringBuilder
.
Agregando a la respuesta @paxdiablo, aquí hay una implementación de muestra de un replaceAll usando StringBuffers que es ~ 3.7 veces más rápido que String.replaceAll():
Código:
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();
}
}
caso de prueba - La salida es la siguiente (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);
}
Cuando usted está reemplazando caracteres individuales , considere iterar sobre su matriz de caracteres, pero reemplace caracteres utilizando un HashMap<Character, Character>()
(previamente creado).
Utilizo esta estrategia para convertir una cadena de exponente entero por caracteres de superíndice Unicode.
Es aproximadamente el doble de rápido en comparación con String.replace(char, char)
. Tenga en cuenta que el tiempo asociado a la creación del mapa hash no está incluido en esta comparación.
El siguiente código es aprox. 30 veces más rápido si no hay coincidencia y 5 veces más rápido si hay una coincidencia.
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. Alternativas más rápidas a .Distinct()
- 2. Alternativas más rápidas a cvFindContour()
- 3. ¿Alternativas más rápidas/más eficientes al Ruby's Marshal?
- 4. ¿Cuáles son algunas alternativas más rápidas a Java2d?
- 5. Alternativas más rápidas al algoritmo de Dijkstra para el sistema de GPS
- 6. Java Regex - Usar el método replaceAll de String para reemplazar líneas nuevas
- 7. Formas más rápidas para buscar en una lista de C# <String> para las subcadenas
- 8. Quiero reemplazar una Cadena completa con un nuevo valor utilizando el método String replaceAll en Java
- 9. Funciones transcendentes/trigonométricas rápidas para Java
- 10. Inserciones a granel más rápidas en sqlite3?
- 11. Cómo reemplazar un carácter más String.replaceAll utilizando el método de Java
- 12. ¿Datastructuras fundamentales más rápidas en máquinas multinúcleo?
- 13. ¿Qué es "String args []"? parámetro en el método principal Java
- 14. ¿La solución más eficiente para leer CLOB en String, y String to CLOB en Java?
- 15. Lua String reemplazar
- 16. Java: Eficiencia del método readLine del BufferedReader y posibles alternativas
- 17. Colecciones de cadenas rápidas en Java
- 18. Forzar clases secundarias para reemplazar el método
- 19. Razor String Reemplazar
- 20. reemplazar el método principal
- 21. Java isEmpty() undefined para String?
- 22. Variable insensible a mayúsculas/minúsculas para String replaceTodo (,) método Java
- 23. std :: string :: reemplazar implementación estándar?
- 24. String ... parámetro en Java
- 25. ¿Cómo se implementa el método String # intern() de Java?
- 26. Alternativas a métodos estáticos en Java
- 27. Solicitudes/respuestas Ajax: ¿cómo hacerlas más rápidas?
- 28. llamar a otro método en el principal método en Java
- 29. Alternativas eficientes para fusionar para data.frames más grandes R
- 30. ¿Qué algoritmos usan los servidores DNS para búsquedas más rápidas?
heh heh replace replace – ojblass
¿Usted usa strings? ¿estas loco? usa array de byte! – IAdapter