开发者

C# - swap Last,First MI fastest way

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜