Tengo un búfer de cadena de aproximadamente 2000 caracteres y necesito verificar el búfer si contiene una cadena específica.
Hará la verificación en una aplicación web ASP.NET 2.0 para cada webrequest.
¿Alguien sabe si el método String.Contains funciona mejor que el método String.IndexOf ?
// 2000 characters in s1, search token in s2
string s1 = "Many characters. The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2);
int i;
i = s1.IndexOf(s2);
Respuestas:
Contains
llamadasIndexOf
:Que llama
CompareInfo.IndexOf
, que en última instancia usa una implementación CLR.Si desea ver cómo se comparan las cadenas en CLR, esto se lo mostrará (busque CaseInsensitiveCompHelper ).
IndexOf(string)
no tiene opciones yContains()
utiliza una comparación ordinal (una comparación byte a byte en lugar de intentar realizar una comparación inteligente, por ejemplo, e con é).Por
IndexOf
lo tanto, será un poco más rápido (en teoría), ya queIndexOf
va directamente a una búsqueda de cadena usando FindNLSString de kernel32.dll (¡el poder del reflector!).Actualizado para .NET 4.0 : IndexOf ya no usa la comparación ordinal, por lo que Contains puede ser más rápido. Vea el comentario a continuación.
fuente
IndexOf()
hecho usaStringComparison.CurrentCulture
yContains()
usaStringComparison.Ordinal
que será más rápido. Pero realmente las diferencias de velocidad de las que estamos hablando son mínimas: el punto es que uno llama al otro, y Contiene es más legible si no necesita el índice. En otras palabras, no se preocupe por eso.Probablemente, no importará en absoluto. Lea esta publicación sobre Coding Horror;): http://www.codinghorror.com/blog/archives/001218.html
fuente
Contains (s2) es muchas veces (en mi computadora 10 veces) más rápido que IndexOf (s2) porque Contains usa StringComparison.Ordinal que es más rápido que la búsqueda sensible a la cultura que IndexOf hace por defecto (pero eso puede cambiar en .net 4.0 http: //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx ).
Contiene tiene exactamente el mismo rendimiento que IndexOf (s2, StringComparison.Ordinal)> = 0 en mis pruebas, pero es más corto y deja en claro su intención.
fuente
Estoy ejecutando un caso real (a diferencia de un punto de referencia sintético)
versus
Es una parte vital de mi sistema y se ejecuta 131,953 veces (gracias DotTrace).
Por sorprendente que sea la sorpresa , el resultado es el opuesto al esperado
: - /
net framework 4.0 (actualizado el 13-02-2012)
fuente
INT
es mucho más grande queBOOL
, yIndexOf>=0
causa un paso másAl usar Reflector, puede ver que Contains se implementa usando IndexOf. Aquí está la implementación.
Es probable que Contains sea un poco más lento que llamar a IndexOf directamente, pero dudo que tenga alguna importancia para el rendimiento real.
fuente
Si realmente desea optimizar su código, su mejor enfoque es siempre la evaluación comparativa.
El marco .net tiene una excelente implementación de cronómetro: System.Diagnostics.Stopwatch
fuente
A partir de una pequeña lectura, parece que bajo el capó el método String.Contains simplemente llama a String.IndexOf. La diferencia es que String.Contains devuelve un valor booleano, mientras que String.IndexOf devuelve un número entero con (-1) que representa que no se encontró la subcadena.
Sugeriría escribir una pequeña prueba con aproximadamente 100,000 iteraciones y verlo usted mismo. Si tuviera que adivinar, diría que IndexOf puede ser un poco más rápido, pero como dije, es solo una suposición.
Jeff Atwood tiene un buen artículo sobre cuerdas en su blog . Se trata más de concatenación, pero de todos modos puede ser útil.
fuente
Solo como una actualización de esto, he estado haciendo algunas pruebas y siempre que su cadena de entrada sea bastante grande, entonces Regex paralelo es el método C # más rápido que he encontrado (siempre que tenga más de un núcleo, imagino)
Obtener la cantidad total de coincidencias, por ejemplo:
¡Espero que esto ayude!
fuente
Utilice una biblioteca de referencia, como esta reciente incursión de Jon Skeet para medirla.
Caveat Emptor
Como todas las preguntas de (micro) rendimiento, esto depende de las versiones del software que esté utilizando, los detalles de los datos inspeccionados y el código que rodea la llamada.
Como todas las preguntas de (micro) rendimiento, el primer paso debe ser obtener una versión en ejecución que se pueda mantener fácilmente. Luego, la evaluación comparativa, la creación de perfiles y el ajuste se pueden aplicar a los cuellos de botella medidos en lugar de adivinar.
fuente
Para cualquiera que siga leyendo esto, indexOf () probablemente funcionará mejor en la mayoría de los sistemas empresariales, ya que contains () no es compatible con IE.
fuente