No pretendo ser un experto en esta área, sin embargo me sentí obligado a al menos perfilar esto hasta cierto punto (sabiendo muy bien que mi escenario ficticio diferirá sustancialmente del suyo) y esto es lo que se le ocurrió:
parece, al menos para mí, EndsWith
está a la cabeza con LastIndexOf
viniendo constantemente en segundo lugar, algunos horarios son:
SubString: 00:00:00.0191877
Contains: 00:00:00.0201980
CompareInfo: 00:00:00.0255181
EndsWith: 00:00:00.0120296
LastIndexOf: 00:00:00.0133181
Estos fueron recogidos de procesamiento de 100.000 cuerdas donde apareció el sufijo deseado en todos cadenas y para mí simplemente se hace eco de la respuesta de Jon (donde el beneficio es a la vez la velocidad y la descriptividad). Y el código utilizado para llegar a estos resultados:
class Program
{
class Profiler
{
private Stopwatch Stopwatch = new Stopwatch();
public TimeSpan Elapsed { get { return Stopwatch.Elapsed; } }
public void Start()
{
Reset();
Stopwatch.Start();
}
public void Stop()
{
Stopwatch.Stop();
}
public void Reset()
{
Stopwatch.Reset();
}
}
static string suffix = "_sfx";
static Profiler profiler = new Profiler();
static List<string> input = new List<string>();
static List<string> output = new List<string>();
static void Main(string[] args)
{
GenerateSuffixedStrings();
FindStringsWithSuffix_UsingSubString(input, suffix);
Console.WriteLine("SubString: {0}", profiler.Elapsed);
FindStringsWithSuffix_UsingContains(input, suffix);
Console.WriteLine("Contains: {0}", profiler.Elapsed);
FindStringsWithSuffix_UsingCompareInfo(input, suffix);
Console.WriteLine("CompareInfo: {0}", profiler.Elapsed);
FindStringsWithSuffix_UsingEndsWith(input, suffix);
Console.WriteLine("EndsWith: {0}", profiler.Elapsed);
FindStringsWithSuffix_UsingLastIndexOf(input, suffix);
Console.WriteLine("LastIndexOf: {0}", profiler.Elapsed);
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
static void GenerateSuffixedStrings()
{
for (var i = 0; i < 100000; i++)
{
input.Add(Guid.NewGuid().ToString() + suffix);
}
}
static void FindStringsWithSuffix_UsingSubString(IEnumerable<string> strings, string suffix)
{
output.Clear();
profiler.Start();
foreach (var s in strings)
{
if(s.Substring(s.Length - 4) == suffix)
output.Add(s);
}
profiler.Stop();
}
static void FindStringsWithSuffix_UsingContains(IEnumerable<string> strings, string suffix)
{
output.Clear();
profiler.Start();
foreach (var s in strings)
{
if (s.Contains(suffix))
output.Add(s);
}
profiler.Stop();
}
static void FindStringsWithSuffix_UsingCompareInfo(IEnumerable<string> strings, string suffix)
{
var ci = CompareInfo.GetCompareInfo("en-GB");
output.Clear();
profiler.Start();
foreach (var s in strings)
{
if (ci.IsSuffix(s, suffix))
output.Add(s);
}
profiler.Stop();
}
static void FindStringsWithSuffix_UsingEndsWith(IEnumerable<string> strings, string suffix)
{
output.Clear();
profiler.Start();
foreach (var s in strings)
{
if (s.EndsWith(suffix))
output.Add(s);
}
profiler.Stop();
}
static void FindStringsWithSuffix_UsingLastIndexOf(IEnumerable<string> strings, string suffix)
{
output.Clear();
profiler.Start();
foreach (var s in strings)
{
if (s.LastIndexOf(suffix) == s.Length - 4)
output.Add(s);
}
profiler.Stop();
}
}
EDIT:
Como se ha comentado, he tratado esto de nuevo con sólo algunas de las cadenas que tienen un sufijo aplicado y estos son los resultados:
SubString: 00:00:00.0079731
Contains: 00:00:00.0243696
CompareInfo: 00:00:00.0334056
EndsWith: 00:00:00.0196668
LastIndexOf: 00:00:00.0229599
El método generador de secuencia se actualiza como sigue, para producir las cadenas:
static void GenerateSuffixedStrings()
{
var nxt = false;
var rnd = new Random();
for (var i = 0; i < 100000; i++)
{
input.Add(Guid.NewGuid().ToString() +
(rnd.Next(0, 2) == 0 ? suffix : string.Empty));
}
}
Además, esta tendencia continúa, si ninguno de la cadena tiene un sufijo:
SubString: 00:00:00.0055584
Contains: 00:00:00.0187089
CompareInfo: 00:00:00.0228983
EndsWith: 00:00:00.0114227
LastIndexOf: 00:00:00.0199328
Sin embargo, esta brecha se acorta de nuevo cuando la asignación de una cuarta parte de las entradas de un sufijo (el primer trimestre, a continuación, la clasificación a randomise
la cobertura):
SubString: 00:00:00.0302997
Contains: 00:00:00.0305685
CompareInfo: 00:00:00.0306335
EndsWith: 00:00:00.0351229
LastIndexOf: 00:00:00.0322899
¿Conclusión?OMI, y de acuerdo con Jon, EndsWith
parece el camino a seguir (basado en esta prueba limitada, de todos modos).
Además Editar:
para curar la curiosidad de Jon me encontré con algunas pruebas más en EndsWith
, con y sin comparación Ordinal
cadena ...
En 100.000 cuerdas con un cuarto de ellos sufijo:
EndsWith: 00:00:00.0795617
OrdinalEndsWith: 00:00:00.0240631
En 1,000,000 cuerdas con un cuarto de ellos sufijo:
EndsWith: 00:00:00.5460591
OrdinalEndsWith: 00:00:00.2807860
En 10.000.000 cuerdas con una cuarta parte de ellos con el sufijo:
EndsWith: 00:00:07.5889581
OrdinalEndsWith: 00:00:03.3248628
Tenga en cuenta que sólo corrió la última prueba una vez como la generación de las cuerdas demostró este portátil está en la necesidad de un reemplazo
Sin comentarios sobre lo que está haciendo .NET, pero si necesita probar la misma cadena para muchos sufijos, puede ser aconsejable construir un árbol de sufijos: http://en.wikipedia.org/wiki/Suffix_tree – mquander