понедельник, 20 апреля 2009 г.

Красота string.Empty или скорость“”?

Для разработки небольшого парсера, решил вынести все значения ключевых слов в конструкцию switch. Так как пустая строка также предусматривается, то решил воспользоваться гламурным string.Empty в кейсе:

static void Main(string[] args)
{
string token = " ";
switch (token.Trim())
{
case string.Empty:

break;
}
}


Я очень удивился, когда компилятор выдал ошибку, что в строке
case string.Empty:
требуется констанотное вырожение.
Лезем в Object Browser и смотрим декларацию string.Empty:

public static readonly string Empty в классе String.

Почему не константа?! Может быть, есть какое-то сверх объяснение, связанное со сверх оптимизациями и прочей магией?
Погуглив на это тему, обнаружил замечательную статью:
string.Empty Example and Issues in C#
Оказывается, что даже при использовании в конструкции if, сравнение со string.Empty работает в два раза медленнее, чем с константной пустой строкой "":

=== string.Empty benchmarked code ===

if (string.Empty == null)
{
throw new Exception();
}

=== Constant string benchmarked code ===

if ("" == null)
{
throw new Exception();
}

=== Benchmark results ===
Second loop was completely compiled out before runtime.
1000000000 iterations.

string.Empty loop: 637 ms
"" loop: 319 ms [faster]


Я не отказываюсь от использования string.Empty, но теперь призадумаюсь о том, стоит ли использовать такую запись пустой строки на конкретном участке кода.

3 коммент.:

Александр комментирует...

Так сравнивать нехорошо. Если говорить не о switch, то проверку пуста строка или нет, надо делать либо через string.IsNullOrEmpty, либо через str.Length (если длина строки равна нулю, то она пустая). Соответственно перед switch достаточно строку проверить одним из этих двух способов.

DmytroZ комментирует...

Все таки да, string.IsNullOrEmpty и str.Length это самые быстрые способы проверить, пустая ли строка.

Роман Ленко комментирует...

String.Empty не создаёт новую инстанцию при передаче её в качестве параметра функции, например, в то время как "" всегда будет создавать новую инстанцию типа System.String. Поэтому, при сравнении следует использовать "", в то время как при передаче параметра (ссылка на объект) следует использовать String.Empty.

Readonly это поле сделано для того, чтобы нельзя было изменить его значение из вне (например, если какае-то функция получила ссылку на String.Empty в качестве параметра и, по неумению прогера, была попытка изменить значение параметра — будет выброшено исключение.)

Отправить комментарий

 

.NET ate my MOSK;. Powered By Blogger © 2009 Bombeli | Theme Design: ooruc