Juste pour le plaisir, j'ai écrit un petit point de repère pour PERF-test de toutes ces réponses (y compris mon autre réponse ci-dessus). Les résultats ici sur mon poste (32 bits Core 2 Duo @ 2.66GHz) pour 5 millions de répétitions en utilisant une version Release:
- LINQ: 10.545 secondes
- mon chemin de Split + StringBuilder: 3.633 secondes
- de Split de wipeck -et-Join façon! : 3,32 secondes
- (décompilé) regex: 3.845 secondes
- (compilé) regex: 12.431 secondes
Résultats: de wipeck fendit et-Join solution gagne, mais la solution de regex (sélectionné OP-) était seulement 15% plus lent, ce qui m'a surpris. Je m'attendais à 100% ou plus pire. Bravo aux développeurs .NET Regex pour la rapidité. Ma propre solution (en utilisant Split et StringBuilder) a été, je pense, optimisée pour la vitesse, mais nécessite beaucoup plus de code et ne rend pas vraiment rapide. Doh! Plus étonnamment, j'ai essayé une solution regex compilée et elle était presque 3x plus lente que la regex non compilée (et je n'ai pas inclus le temps de compilation dans les résultats - y compris la compilation ce serait encore pire). Tellement pour l'avantage compilé de performance de regex. LINK était, comme je m'y attendais, vraiment lent - le surcoût de tous ces objets supplémentaires et appels de méthode s'ajoute vraiment.
est ici le code de test:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
class Timer : IDisposable
{
private DateTime _start;
private string _name;
public Timer(string name)
{
_name = name;
_start = DateTime.Now;
}
public void Dispose()
{
TimeSpan taken = DateTime.Now - _start;
Console.WriteLine(string.Format ("{0} : {1} seconds", _name, taken.TotalMilliseconds/1000.0));
}
}
class Program
{
static void Main(string[] args)
{
int reps = 5000000;
string oldString = "200 abc def abc [a18943]";
using (new Timer("LINQ"))
{
for (int n = 0; n < reps; n++)
{
string[] a = oldString.Split(' ');
var result = a.Skip(a.Length - 1)
.Select(w => w.Replace("[", "").Replace("]", ""))
.Concat(a.Take(a.Length - 1).Skip(1)).ToArray();
var newString = string.Join(" ", result);
}
}
using (new Timer("my Split + StringBuilder way"))
{
for (int n = 0; n < reps; n++)
{
string[] words = oldString.Split(' ');
StringBuilder sb = new StringBuilder(words[words.Length - 1].Trim('[', ']'));
for (int i = 1; i < words.Length - 1; i++)
{
sb.Append(' ');
sb.Append(words[i]);
}
string newString = sb.ToString();
}
}
using (new Timer("wipeck's Split-and-Join way!"))
{
for (int n = 0; n < reps; n++)
{
string valueString = "200 abc def abc [a18943]";
string[] values = valueString.Split(' ');
string lastWord = values[values.Length - 1];
lastWord = lastWord.Trim('[', ']');
values[0] = lastWord;
string movedValueString = string.Join(" ", values, 0, values.Length - 1);
}
}
using (new Timer("(uncompiled) regex"))
{
for (int n = 0; n < reps; n++)
{
string newString = Regex.Replace(@"^(\w+)(.+) \[(\w+)\]$", oldString, "$3$2");
}
}
Regex regex = new Regex(@"^(\w+)(.+) \[(\w+)\]$", RegexOptions.Compiled);
string newStringPreload = regex.Replace(oldString, "$3$2");
using (new Timer("(compiled) regex"))
{
for (int n = 0; n < reps; n++)
{
string newString = regex.Replace(oldString, "$3$2");
}
}
}
}
+1, très concis. –
Son travaillé Je veux juste comprendre comment il woring – NETQuestion
Très propre. J'aime ça. Je me demande juste si RegEx est exagéré ici? –