2011-07-11 24 views
6

He estado trabajando con algunos programas aquí en el trabajo durante aproximadamente un mes que tienen un montón de análisis de cadenas y cosas así. Me han aconsejado usar una matriz de caracteres para estas cosas en lugar de una cadena porque la matriz de caracteres es más rápida. Entiendo por qué una matriz de caracteres es rápida, pero ¿qué tiene que ver con el tipo de cadena que la hace más lenta? ¿Qué estructura de datos está implementando y hay alguna manera de hacerlo tan rápido como una matriz de caracteres?tipo de cadena .NET frente a la matriz de caracteres

Respuesta

13

La diferencia más obvia es que string es inmutable. Por lo tanto, no puede modificar partes de este y necesita crear una copia completamente nueva en cada modificación.

La cadena en sí tiene una implementación muy especial (es una clase de tamaño variable) y no está respaldada por una matriz. No veo ninguna razón por la que el acceso de solo lectura a char s en una cadena sea lento.

Así que si quiere cambiar las partes pequeñas de una cadena, necesita usar StringBuilder o char[]. De estos dos char[] es/era más rápido desde StringBuilder tiene verificaciones e indirecciones adicionales. Pero como se trata de un detalle de implementación, podría haber cambiado desde la última vez que lo probé.


Justo como punto de referencia, y como de .NET 4 Configuración de un miembro de char[] es aproximadamente cuatro veces más rápido en comparación con un StringBuilder. Pero ambos pueden hacer más de 200 millones de asignaciones por segundo, por lo que rara vez importa en la práctica.

La lectura de un char[] es un poco más rápida (25% para mi código de prueba) que la lectura de string. La lectura de StringBuilder por otro lado es más lenta (un factor de 3) que la lectura de char[].

En todos los puntos de referencia descuidé la sobrecarga de mi otro código. Esto significa que mi prueba subestima un poco las diferencias.

Mi conclusión es que mientras que char[] es más rápido que las alternativas, solo importa si vas a superar los cientos de megabytes por segundo.


//Write StringBuilder 
StringBuilder sb = new StringBuilder(); 
sb.Length = 256; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sb[j] = 'A'; 
} 

//Write char[] 
char[] cs = new char[256]; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    cs[j] = 'A'; 
} 

// Read string 
string s = new String('A',256); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

//Read char[] 
char[] s = new String('A',256).ToCharArray(); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

//Read StringBuilder 
StringBuilder s= new StringBuilder(new String('A',256)); 
int sum = 0; 
for(int i=0; i<1000000000; i++) 
{ 
    int j = i&255; 
    sum += s[j]; 
} 

(Sí, sé que mi código de prueba no es muy buena, pero no creo que hace una gran diferencia.)

+0

No es el aumento de rendimiento con cadenas en términos de memoria como todas las cuerdas están internados. – koumides

+0

@koumides Solo se encuetran los literales y las cadenas en los que se interna explícitamente. – CodesInChaos

1

La ventaja de las matrices de caracteres sobre cadenas es que puede alterar las matrices de caracteres en su lugar; en C# las cadenas son inmutables, por lo que cualquier cambio crea un nuevo objeto en el montón con una versión modificada de la cadena. En una matriz de caracteres puede hacer muchos cambios sin asignar nada en el montón.

Cuestiones relacionadas