Entonces, después de ver la publicación de Adam Ralph, sospeché que su solución era más rápida que la solución Regex. Solo pensé en compartir los resultados de mis pruebas ya que descubrí que era más rápido.
realidad, hay dos factores en juego (ignorando las variables del sistema): número de sub-cadenas extraídas (determinado por el número de delimitadores), y la longitud total de cadena. El escenario muy simple representado a continuación utiliza "A" como la subcadena delimitada por dos espacios en blanco (un espacio seguido de una pestaña). Esto acentúa el efecto del número de subcadenas extraídas. Continué e hice algunas pruebas de variables múltiples para llegar a las siguientes ecuaciones generales para mi sistema operativo.
Regex()
t = (28,33 * SSL + 572) (SSN/10^6)
split(). Donde()
t = (6.23 * SSL + 250) (SSN/10^6)
Donde t es el tiempo de ejecución en milisegundos, SSL es la longitud promedio de la subcadena y el SSN es el número de subcadenas delimitadas en la cadena.
Estas ecuaciones pueden también escrito como
t = (28,33 * SL + 572 * SSN)/10^6
y
t = (6,23 * SL + 250 * SSN)/10^6
donde SL es la longitud total de cadena (SL = SSL * SSN)
Conclusión:. la división() cuando() la solución es más rápida que Regex(). El factor principal es el número de subcadenas, mientras que la longitud de la secuencia juega un papel menor. Las ganancias de rendimiento son aproximadamente 2x y 5x para los respectivos coeficientes.
Aquí está mi código de prueba (probablemente manera más material del necesario, pero es puesta a punto para obtener los datos de múltiples variables que habló)
using System;
using System.Linq;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace ConsoleApplication1
{
class Program
{
public enum TestMethods {regex, split};
[STAThread]
static void Main(string[] args)
{
//Compare TestMethod execution times and output result information
//to the console at runtime and to the clipboard at program finish (so that data is ready to paste into analysis environment)
#region Config_Variables
//Choose test method from TestMethods enumerator (regex or split)
TestMethods TestMethod = TestMethods.split;
//Configure RepetitionString
String RepetitionString = string.Join(" \t", Enumerable.Repeat("A",100));
//Configure initial and maximum count of string repetitions (final count may not equal max)
int RepCountInitial = 100;int RepCountMax = 1000 * 100;
//Step increment to next RepCount (calculated as 20% increase from current value)
Func<int, int> Step = x => (int)Math.Round(x/5.0, 0);
//Execution count used to determine average speed (calculated to adjust down to 1 execution at long execution times)
Func<double, int> ExecutionCount = x => (int)(1 + Math.Round(500.0/(x + 1), 0));
#endregion
#region NonConfig_Variables
string s;
string Results = "";
string ResultInfo;
double ResultTime = 1;
#endregion
for (int RepCount = RepCountInitial; RepCount < RepCountMax; RepCount += Step(RepCount))
{
s = string.Join("", Enumerable.Repeat(RepetitionString, RepCount));
ResultTime = Test(s, ExecutionCount(ResultTime), TestMethod);
ResultInfo = ResultTime.ToString() + "\t" + RepCount.ToString() + "\t" + ExecutionCount(ResultTime).ToString() + "\t" + TestMethod.ToString();
Console.WriteLine(ResultInfo);
Results += ResultInfo + "\r\n";
}
Clipboard.SetText(Results);
}
public static double Test(string s, int iMax, TestMethods Method)
{
switch (Method)
{
case TestMethods.regex:
return Math.Round(RegexRunTime(s, iMax),2);
case TestMethods.split:
return Math.Round(SplitRunTime(s, iMax),2);
default:
return -1;
}
}
private static double RegexRunTime(string s, int iMax)
{
Stopwatch sw = new Stopwatch();
sw.Restart();
for (int i = 0; i < iMax; i++)
{
System.Collections.Generic.IEnumerable<string> ens = Regex.Split(s, @"\s+");
}
sw.Stop();
return Math.Round(sw.ElapsedMilliseconds/(double)iMax, 2);
}
private static double SplitRunTime(string s,int iMax)
{
Stopwatch sw = new Stopwatch();
sw.Restart();
for (int i = 0; i < iMax; i++)
{
System.Collections.Generic.IEnumerable<string> ens = s.Split().Where(x => x != string.Empty);
}
sw.Stop();
return Math.Round(sw.ElapsedMilliseconds/(double)iMax, 2);
}
}
}
Consulte también la posibilidad de duplicar con SplitStringOptions para eliminar el espacio en blanco adicional. http://stackoverflow.com/questions/6111298/best-way-to-specify-whitespace-in-a-string-split-operation – goodeye