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

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

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

Переверните строку: "A B C D E" в массив: Строка [ "А", "В", "С", "D", "Е"]

Мой алгоритм выглядит следующим образом:

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% ВСЕГО времени выполнения? (Особенно, так как я ожидал, что другие области будут использовать больше ЦП) Единственная идея, которую я придумаю с / это C # - это попытка подсчитать длину строки, что, как говорят мне люди, не так (что это больше похоже на строки VB, я думаю, ?). Но это не имеет смысла для временных затрат.

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

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

Ответы [ 4 ]

3 голосов
/ 02 августа 2010

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

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

//
public string[] SplitOnMultiSpaces(string text)
{
    return text.Split(splitter, StringSplitOptions.RemoveEmptyEntries );
}
2 голосов
/ 02 августа 2010

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

1 голос
/ 02 августа 2010

Вы можете просто заменить

var split = text.Split(' ');

на

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

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

0 голосов
/ 02 августа 2010

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

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

...