¿Alguien sabe por qué la función StartsWith de C# (.NET) es considerablemente más lenta que IsPrefix?¿Por qué la función es prefijo más rápido que se inicia con C#?
Respuesta
Creo que sobre todo ir a buscar la cultura actual del hilo.
Si cambia la prueba de Marc a utilizar esta forma de String.StartsWith
:
Stopwatch watch = Stopwatch.StartNew();
CultureInfo cc = CultureInfo.CurrentCulture;
for (int i = 0; i < LOOP; i++)
{
if (s1.StartsWith(s2, false, cc)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
se trata de mucho más cerca.
Si utiliza s1.StartsWith(s2, StringComparison.Ordinal)
Es mucho más rápido que usar CompareInfo.IsPrefix
(dependiendo de la CompareInfo
por supuesto). En mi caja de los resultados son (no científico):
- s1.StartsWith (S2): 6914ms
- s1.StartsWith (S2, falsa, cultura): 5568ms
- compare.IsPrefix (S1, S2): 5200ms
- s1.StartsWith (s2, StringComparison.Ordinal): 1393ms
Obviamente eso es porque no deja de ser la comparación de enteros de 16 bits en cada punto, que es bastante barato. Si no desea quiere una verificación sensible a la cultura, y el rendimiento es particularmente importante para usted, esa es la sobrecarga que usaría.
StartsCon llamadas internas de IsPrefix. Asigna información cultural antes de llamar a IsPrefix.
Buena pregunta; para una prueba, consigo: Plataforma
9156ms; chk: 50000000
6887ms; chk: 50000000
prueba:
using System;
using System.Diagnostics;
using System.Globalization;
class Program
{
static void Main()
{
string s1 = "abcdefghijklmnopqrstuvwxyz", s2 = "abcdefg";
const int LOOP = 50000000;
int chk = 0;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
if (s1.StartsWith(s2)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
chk = 0;
watch = Stopwatch.StartNew();
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
for (int i = 0; i < LOOP; i++)
{
if (ci.IsPrefix(s1, s2)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
}
}
Consulte la fuente de IsPrefix. El problema es que, en algunos casos, va a ser más lento que StartsWith
solo porque realmente usa StartsWith y hace pocas operaciones más.
[System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual bool IsPrefix(String source, String prefix, CompareOptions options)
{
if (source == null || prefix == null) {
throw new ArgumentNullException((source == null ? "source" : "prefix"),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
int prefixLen = prefix.Length;
if (prefixLen == 0)
{
return (true);
}
if (options == CompareOptions.OrdinalIgnoreCase)
{
return source.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
}
if (options == CompareOptions.Ordinal)
{
return source.StartsWith(prefix, StringComparison.Ordinal);
}
if ((options & ValidIndexMaskOffFlags) != 0) {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
}
// to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
// the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
return (InternalFindNLSStringEx(
m_dataHandle, m_handleOrigin, m_sortName,
GetNativeCompareFlags(options) | Win32Native.FIND_STARTSWITH | ((source.IsAscii() && prefix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
source, source.Length, 0, prefix, prefix.Length) > -1);
}
- 1. ¿Por qué compila C# mucho más rápido que C++?
- 2. ¿C++/CLI es más rápido que C#
- 3. Por qué unir es más rápido que la concatenación normal
- 4. ¿Por qué String.IsNullOrEmpty es más rápido que String.Length?
- 5. ¿Es + = más rápido que - =?
- 6. ¿Por qué MSMQ es más rápido que WCF QueueService?
- 7. ¿Por qué file_get_contents es más rápido que memcache_get?
- 8. Por qué Array.reverse_each es más rápido que Array.reverse.each
- 9. cuando es Java más rápido que C++ (o cuando JIT es más rápido que precompilado)?
- 10. ¿Por qué \% (\) es más rápido que \ (\) en Vim?
- 11. ¿Cuál es más rápido y por qué?
- 12. ¿Por qué es === más rápido que == en PHP?
- 13. ¿Por qué i = i + 1 es más rápido que i ++?
- 14. ¿Por qué es Select 1 más rápido que Select count (*)?
- 15. ¿C es más rápido que VB.NET?
- 16. ¿Por qué C++ lambda es más lento que la función común cuando se llama varias veces?
- 17. CLR de F # y C# es lo mismo que por qué F # es más rápido que C#
- 18. Preincremento más rápido que poscreción en C++ - ¿cierto? Si es así, ¿por qué es?
- 19. ¿Es `extender` más rápido que` + = `?
- 20. ¿Por qué mi código es más rápido cuando se ejecuta con Performance Analysis?
- 21. ¿Por qué la función fwrite libc es más rápida que la función de escritura syscall?
- 22. ¿Por qué no es más rápido usando colecciones paralelas?
- 23. ¿Por qué mi string.indexof (char) es más rápido?
- 24. ¿Por qué el mapa sería mucho más rápido que unordered_map?
- 25. ¿Por qué este programa OCaml es más rápido que mi programa C?
- 26. ¿Es MATLAB más rápido que Python?
- 27. ¿doble o flotante, que es más rápido?
- 28. que es más rápido? Declaración o PreparedStatement
- 29. C# TPL más rápido que C++ PPL?
- 30. ¿Por qué es esta consulta basada gama mucho más rápido