C # - swap Last, First MI самый быстрый способ - PullRequest
1 голос
/ 01 июля 2010

Хорошо, я могу, конечно, сделать это с некоторым IndexOf или даже с Split (), но я подумал, что выкину это как тизер производительности.

У меня есть данные - например, 100K из них - в LastName, FirstName Mi, и мне нужно сделать это FirstName Mi Lastname.

Я думаю, что SubString / IndexOf (',') может выполнить эту работу, но надеялся на более элегантное / производительное предложение.

Есть идеи получше?

Ответы [ 2 ]

6 голосов
/ 01 июля 2010

.Split, вероятно, самый быстрый / краткий. Однако .IndexOf на удивление является самым быстрым в небольших тестах для этого случая (где мы можем положиться на две запятые и использовать LastIndexOf).

Вставьте приведенный ниже код в LINQPad , чтобы проверить себя:

Для 10 000 000 результатов (лучший показатель, так как ранние результаты могут сильно варьировать), я получаю:

Регулярное время 00: 00: 54.1151103

Время разделения 00: 00: 21.6187375

IndexOf Time 00: 00: 24.2403165

За 1000000 результатов я получаю:

Регулярное время 00: 00: 03.6016272

Время разделения 00: 00: 01.5575928

IndexOf Time 00: 00: 00.9774164

За 100 000 результатов я получаю:

Регулярное время 00: 00: 00.2587501

Время разделения 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");  
}  
3 голосов
/ 01 июля 2010

Как бы вы это ни делали, I / O будет самым большим временем, отведенным для этой операции.Вероятно, вам потребовалось бы больше времени, чтобы набрать вопрос, чем запустить программу, выполняющую обмен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...