Ok, I can certainly do this with some IndexOf, or even a Split(), but I thought I'd throw this out as a bit of a performance teaser.
I have data - like 100K's of these - in LastName,FirstName Mi and I need to make it Fi开发者_Python百科rstName Mi Lastname.
I think that SubString/IndexOf(',') can do the job, but was hoping for a more elegant/performant suggestion.
Any better ideas?
.Split is probably the fastest/most concise. However .IndexOf is surprisingly the fastest in small tests for this case (where we can rely on two commas and use LastIndexOf).
Paste the code below into LINQPad to test for yourself:
For 10,000,000 results (best indicator as early results could be highly variable) I get:
Regex Time 00:00:54.1151103
Split Time 00:00:21.6187375
IndexOf Time 00:00:24.2403165
For 1,000,000 results I get:
Regex Time 00:00:03.6016272
Split Time 00:00:01.5575928
IndexOf Time 00:00:00.9774164
For 100,000 results I get:
Regex Time 00:00:00.2587501
Split Time 00:00:00.1013721
IndexOf Time 00:00:00.0980560
void Main()
{
int count = 100000;
WithRegex(count);
WithSplit(count);
WithIndexOf(count);
}
void WithRegex(int count)
{
Regex _commaRegex = new Regex(@",", RegexOptions.Compiled);
string[] names = Enumerable.Range(1,count)
.Select(i => "first,last,middle" + i).ToArray();
List<string> newNames = new List<string>(count);
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
foreach (string name in names)
{
string[] split = _commaRegex.Split(name);
StringBuilder sb = new StringBuilder();
sb.Append(split[0]).Append(split[2]).Append(split[1]);
newNames.Add(sb.ToString());
}
stopWatch.Stop();
stopWatch.Elapsed.Dump("Regex Time");
}
void WithSplit(int count)
{
string[] names = Enumerable.Range(1,count)
.Select(i => "first,last,middle" + i).ToArray();
List<string> newNames = new List<string>(count);
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
foreach (string name in names)
{
string[] split = name.Split(',');
StringBuilder sb = new StringBuilder();
sb.Append(split[0]).Append(split[2]).Append(split[1]);
newNames.Add(sb.ToString());
}
stopWatch.Stop();
stopWatch.Elapsed.Dump("Split Time");
}
void WithIndexOf(int count)
{
string[] names = Enumerable.Range(1,count)
.Select(i => "first,last,middle" + i).ToArray();
List<string> newNames = new List<string>(count);
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
foreach (string name in names)
{
/* This approach only works for 2 commas */
int firstComma = name.IndexOf(',');
int lastComma = name.LastIndexOf(',');
string first = name.Substring(0, firstComma);
string last = name.Substring(firstComma + 1, lastComma-(firstComma+1));
string middle = name.Substring(lastComma + 1);
StringBuilder sb = new StringBuilder();
sb.Append(first).Append(middle).Append(last);
newNames.Add(sb.ToString());
}
stopWatch.Stop();
stopWatch.Elapsed.Dump("IndexOf Time");
}
However you do it, I/O is going to be the greatest time suck in this operation. It would have probably taken you longer to type the question than to actually run the program that makes the swap.
精彩评论