РЕДАКТИРОВАТЬ: Теперь, когда вы предоставили больше контекста:
Пытаясь воспроизвести это, я вообще не смог найти узкое место в string.Length
. Единственный способ сделать это быстрее - это закомментировать и тест , и текст блока if , что не совсем справедливо. Простое комментирование условия замедлило процесс, то есть, безусловно, копирование ссылки было медленнее, чем проверка условия.
Как уже указывалось, использование перегрузки string.Split
, которая удаляет пустые записи для вас, является настоящей убийственной оптимизацией.
Вы можете пойти дальше, избегая создания нового массива char с пробелом в каждый раз. Вы всегда будете эффективно проходить одно и то же, так почему бы не воспользоваться этим?
Пустые массивы эффективно неизменяемы. Вы можете оптимизировать нулевой / пустой регистр, всегда возвращая одно и то же.
Оптимизированный код становится:
private static readonly char[] Delimiters = " ".ToCharArray();
private static readonly string[] EmptyArray = new string[0];
public static string[] SplitOnMultiSpaces(string text)
{
if (string.IsNullOrEmpty(text))
{
return EmptyArray;
}
return text.Split(Delimiters, StringSplitOptions.RemoveEmptyEntries);
}
String.Length
абсолютно не считает буквы в строке. Значение хранится в виде поля - хотя я, кажется, помню, что верхний бит этого поля используется для запоминания того, все ли символы являются ASCII (или использовались в любом случае) для включения других оптимизаций. Таким образом, для доступа к свойству может потребоваться битовая маска, но она все равно будет иметь значение O (1), и я ожидаю, что JIT также ее встроит. (Он реализован как extern
, но, надеюсь, это не повлияет на JIT в этом случае - я подозреваю, что это достаточно распространенная операция, чтобы потенциально иметь специальную поддержку.)
Если вы уже знаете, что строка не равна нулю, тогда ваш существующий тест
if (s.Length != 0)
- лучший способ, если вы ищете необработанную производительность IMO. Лично в большинстве случаев я бы написал:
if (s != "")
, чтобы прояснить, что нас интересует не столько длина, сколько значение, как пустая строка. Это будет немного медленнее, чем проверка длины, но я считаю, что это более понятно. Как и всегда, я бы пошел к самому ясному коду, пока у вас не появятся данные тестов / профилирования, чтобы указать, что это действительно - узкое место. Я знаю, что ваш вопрос явно о поиске наиболее эффективного теста, но я все равно упомянул об этом. У вас есть доказательства того, что это является узким местом?
РЕДАКТИРОВАТЬ: просто, чтобы привести более ясные причины для моего предложения , а не с использованием string.IsNullOrEmpty
: вызов этого метода подсказывает мне, что вызывающая сторона явно пытается разобраться со случаем, когда переменная имеет значение null иначе они бы не упомянули об этом. Если в этой точке кода это считается ошибкой, если переменная равна null, то вам не следует пытаться обрабатывать ее как обычный случай.
В этой ситуации проверка Length
на самом деле лучше в одном смысле, чем предложенный мной тест на неравенство: он действует как неявное утверждение, что переменная не равна нулю. Если у вас есть ошибка, и она равна null, тест выдаст исключение, и ошибка будет обнаружена раньше. Если вы используете тест на равенство, он будет обрабатывать null как отличающийся от пустой строки, поэтому он войдет в тело вашего оператора if. Если вы используете string.IsNullOrEmpty
, он будет считаться нулевым, как пустой, поэтому он не войдет в блок.