C# 4.0, самый эффективный способ определить, равна ли длина строки! = 0? Часть 2

(Мои извинения, это второй пост для наиболее эффективного способ определить, является ли длина строки != 0?, но я не могу понять, как отвечать на ответы людей, мой ответ публикуется как «ответ»)

В идеале я ищу наиболее эффективный алгоритм для выполнения следующего (который будет вызываться более 100 миллионов раз). Я использую С# 4.0

Превратите строку: "A B C D E" в массив: string["A","B","C","D","E"]

Мой алгоритм следующий:

public string[] SplitOnMultiSpaces(string text)
{
  if (string.IsNullOrEmpty(text)) return new string[0];

  var split = text.Split(' ');
  int length = split.Length;

  var data = new string[length];

  int index = 0;
  for (int i = 0; i<length; i++)
  {
    if (split[i].Length != 0)
    {
      data[index++] = split[i];
    }
  }

  return data;
}

Моя проблема в том, что когда я профилирую это против 100 000 строк, для выполнения требуется 1,04 секунды.

Если я закомментирую проверку «if (split[i].Length != 0)», это займет всего 0,2 секунды.

Может ли кто-нибудь сказать мне, почему этот (простой) запрос к строке занимает 80% ОБЩЕГО времени выполнения? (Особенно, поскольку я ожидал, что другие области будут использовать больше ЦП). Единственная идея, которую я придумал, - это С#, пытающийся подсчитать длину строки, что, как мне говорят, не так (что это больше похоже на строки VB, я думаю ?). Но это не имело бы смысла для накладных расходов времени.

Я думал попытаться увидеть, существует ли split[i][0], но использование исключения замедляет работу WAAAAAAY.

P.S. -- Мой алгоритм также страдает тем, что возвращаемый массив чаще всего больше, чем должен быть, но это не кажется слишком большим накладным расходом.


person Eric    schedule 02.08.2010    source источник
comment
Из любопытства, если вас волнует скорость, почему вы используете C#? C++ или C, скорее всего, значительно увеличат скорость.   -  person riwalk    schedule 02.08.2010
comment
При профилировании убедитесь, что Visual Studio НЕ подключена. Это может внезапно стать в миллион раз быстрее. (А может и нет, это действительно зависит.)   -  person Roman Starkov    schedule 02.08.2010
comment
чтобы ответить, вам нужно щелкнуть маленькую ссылку «добавить комментарий» под ответом человека   -  person µBio    schedule 02.08.2010
comment
Какой профайлер используете? Я обнаружил, что профайлер Ants значительно увеличивает время выполнения по сравнению с Dottrace.   -  person Giorgi    schedule 02.08.2010


Ответы (4)


Скорее всего, будет так же быстро или быстрее, чем вы можете сделать (не углубляясь в код более низкого уровня, например C/C++).

// somewhere else
private static readonly char[] splitter =  new []{' '} ;

//
public string[] SplitOnMultiSpaces(string text)
{
    return text.Split(splitter, StringSplitOptions.RemoveEmptyEntries );
}
person µBio    schedule 02.08.2010
comment
+1 за прямой возврат результата Split и сохранение избыточных выделений памяти и копий. Предложение: сделайте new [] {' '} статическим массивом, а не обновляйте его каждый раз. - person ; 02.08.2010

Сравнили производительность, используя перегрузку String.Split, которая принимает StringSplitOptions, что делает проверку пустой строки ненужной?

person Nicole Calinoiu    schedule 02.08.2010

Вы могли бы просто заменить

var split = text.Split(' ');

с

var split = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);

Но это тоже должно быть профилировано.

person Henk Holterman    schedule 02.08.2010

Когда я тестирую это, либо в режиме отладки, либо в режиме выпуска, я получаю практически идентичные времена выполнения независимо от того, есть ли «if (split[i].Length!=0)» или нет, оба соответствуют вашему самому быстрому времени. (Таким образом, поддерживая идею о том, что длина является быстрой проверкой.) Есть ли что-то не показанное, что могло бы каким-то другим образом повлиять на производительность?

Сказав это, я хотел бы согласиться с тем, что StringSplitOptions.RemoveEmptyEntries — лучший способ. Но мне все еще любопытно, почему я не могу воспроизвести исходное поведение.

person TechNeilogy    schedule 02.08.2010