Duplicar posible:
C++ string::find complexityRendimiento std :: strstr vs std :: string :: encontrar
Recientemente he descubierto, que la función std::string::find
es un orden de magnitud más lento que la función std::strstr
- en mi entorno con GCC 4.7 en Linux. La diferencia de rendimiento depende de la longitud de las cadenas y de la arquitectura del hardware.
Sin embargo, hay una razón simple para la diferencia: std::string::find
básicamente llama a std::memcmp
en un bucle - con complejidad de tiempo O(m * n)
. Por el contrario, std::strstr
está altamente optimizado para la arquitectura de hardware (por ejemplo, con instrucciones SSE) y utiliza un algoritmo de coincidencia de cadenas más sofisticado (aparentemente Knuth-Morris-Pratt).
También me sorprendió no encontrar las complejidades de tiempo de estas dos funciones en los documentos de idioma (es decir, borradores N3290 y N1570). Solo he encontrado complejidades de tiempo para char_traits
. Pero eso no ayuda, porque no hay función para la búsqueda de subcadenas en char_traits
.
Supongo que std::strstr
y memmem
contienen optimizaciones similares con un rendimiento casi idéntico. Y hasta hace poco, asumí que std::string::find
usa internamente el memmem
.
Las preguntas son: ¿Hay alguna buena razón, ¿por qué std::string::find
no utiliza std::memmem
? ¿Y esto es diferente con otra implementación?
La pregunta no es: ¿Cuál es la mejor implementación de esta función? Es realmente difícil argumentar a favor de C++, si es más lento que C. No me importaría si ambas implementaciones fueran lentas. Es la diferencia de rendimiento lo que realmente duele.
@FrerichRaabe: Tiene razón, hay una superposición en las dos preguntas. Pero mis preguntas son más específicas, y el otro artículo no responde ninguna de ellas. – nosid
@nosid: sí, lo hace. Mire en particular la explicación adicional en los comentarios de dietmar kuhl sobre el caso promedio frente al peor de los casos y la complejidad del espacio, por qué es muy probable que esto no se use. Esos argumentos no cambian si reutiliza 'std :: memmem' iso implementando el algoritmo desde cero. – KillianDS