.NET 3.5 / C #: есть ли разница в производительности между if () == и! =

2

При использовании оператора if() лучше использовать с точки зрения производительности == или!=

if(object==null)

или

if(object!=null)

Если утверждение w/наивысшей вероятности успеха будет первым в последовательности if()?

  • 1
    люди быстрее ударяют пространство правым большим пальцем по сравнению с большим
  • 1
    С точки зрения производительности это не имеет значения вообще. С точки зрения читабельности, это возможно.
Показать ещё 2 комментария
Теги:

11 ответов

11
Лучший ответ

Я просто проанализировал следующий код в .NET Reflector:

public static void Main(string[] args)
{
    object obj2 = null;
    if (obj2 == null)
    {
        Console.WriteLine("Is null");
    }
    if (obj2 != null)
    {
        Console.WriteLine("Is not null");
    }
}

и вот результат IL:

.method public hidebysig static void Main(string[] args) cil managed
{
    .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
    .maxstack 1
    .locals init (
        [0] object obj2)
    L_0000: ldnull 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: brtrue.s L_000f
    L_0005: ldstr "Is null"
    L_000a: call void [mscorlib]System.Console::WriteLine(string)
    L_000f: ldloc.0 
    L_0010: brfalse.s L_001c
    L_0012: ldstr "Is not null"
    L_0017: call void [mscorlib]System.Console::WriteLine(string)
    L_001c: ret 
}

Из вышесказанного кажется, что это не имеет никакого значения для производительности, если() проверьте, используете ли вы. Но вы можете посмотреть на это так: попробуйте использовать проверку if(), которая, скорее всего, произойдет. Поэтому, если объект редко принимает значение null в точке проверки if, тогда используйте if (object!= Null). +

  • 1
    Хорошо, но IL никогда не выполняется, так что это не говорит нам ничего окончательного. Вам придется проанализировать машинный код, скомпилированный JIT, и даже тогда он скажет вам только о конкретной реализации. Насколько нам известно, это может быть одинаковая скорость на 32-битных процессорах, но разная для 64-битных.
23

Я очень сомневаюсь, что вы заметили какие-либо ощутимые различия; не в последнюю очередь, существуют операторы brtrue и brfalse IL...

Если у вас есть проблемы с производительностью, используйте профилировщик и посмотрите на проблемы реальные; это не будет... это преждевременная оптимизация.

  • 2
    Хорошо сказано. Учитывая отсутствие каких-либо существенных различий в производительности, основной проблемой должна быть ясность кода.
  • 1
    Дело не в том, что проблемы с производительностью существуют, я стараюсь по возможности активно участвовать в оптимизации. Этот вопрос время от времени приходил мне в голову, и я подумал, что было бы полезно получить коллективный ответ.
Показать ещё 1 комментарий
10

Вам все равно.

Если вы заинтересованы в эффективности, вы должны писать на языке низкого уровня. Не .Net.

  • 0
    О, не начинай этот аргумент. Есть случаи, когда C # превосходит C ++ по производительности из-за JIT-оптимизации.
3

9 наносекунды, которые вы получили бы, используя!= вместо! =, были потеряны, задав этот вопрос. Выбор операторов невелик, и эти виды микро-оптимизации не должны влиять на дизайн вашего приложения.

Однако порядок if значителен. С# && и || операторы закорочены, что означает, что если первое условие && false, то С# не будет оценивать второе условие - аналогично, если первое условие || истинно, тогда нет смысла оценивать второе условие.

Вы можете использовать короткое замыкание в своих интересах. Эмпирическое правило состоит в том, чтобы структурировать условия следующим образом:

  • При использовании & &, условия, наиболее вероятно, потерпят неудачу, должны быть первыми.
  • При использовании || условия, наиболее вероятные для успеха, должны быть вторыми.
  • Условия, которые занимают очень много времени, должны наступить.

Используя тривиальный пример:

if(existsInDatabase(username, password) && loginAttempts < 3) { ... }

existsInDatabase может занять много времени, поэтому может потребоваться поездка в базу данных или веб-сервис. Если loginAttempts >= 3, мы потеряли поездку в базу данных. Мы минимизируем наши поездки в базу данных, написав код следующим образом:

if(loginAttempts < 3 && existsInDatabase(username, password)) { ... }

Небольшие настройки, как это, могут иногда иметь огромное значение, но вам действительно нужно профиль, прежде чем делать такие изменения. Если вы потратите 20 часов на разработку, очищаете свой код и переписываете, если утверждения для оптимального выполнения, но вы только ускоряете свое приложение на 0,5 секунды, чистая экономия составляет -19,99 часа. Учитывайте это перед микро-оптимизацией вашего приложения.

3

Старые процессоры, которые использовали статическое предсказание, предположили, что условия являются ложными при заполнении их конвейеров. Я не думаю, что это актуально.

  • 0
    Так что, если это больше не актуально, зачем упоминать об этом?
  • 0
    Потому что он спросил, есть ли разница в производительности между использованием == и! =. Это МОЖЕТ быть чем-то, но маловероятным.
2

Если утверждение w/наивысшее вероятность успеха быть первой в if() последовательность?

Вообще-то да. Использование && и || операторов в логическом выражении будет вызывать оценку короткого замыкания. - если оценка первого элемента делает выражение бесспорно верно, то ни один из других элементов не будет оценена

Что касается == vs. !=, даже если бы была разница в производительности, это никогда не изменит того, что вы заметите.

2

Я бы сказал, что не будет никакой разницы, если код имеет форму: -

if(obj == null)
{
    // blah
}
else
{
    // blah
}

Компилятор переведет ваш оператор if в ветвь, либо brtrue, либо brfalse, которые имеют эквивалентную производительность.

Звучит немного похоже на то, что вы микро-оптимизируете; если вам нужно спросить, вероятно, вы чрезмерно усердны.

Если вы действительно уверены, что будет разница, попробуйте написать код в обоих направлениях и запустить секундомеры вокруг кода или использовать профайлер. Пока вы не измеряете это, это все еще теория, и чаще всего наш инстинкт имеет тенденцию быть более сильным, чем мы хотели бы думать об этом!

1

Я не думаю, что это имеет какое-то значение в отношении производительности. Я предпочитаю всегда сначала проверять положительное состояние - назовите его оптимистичным подходом. Выполнение этого последовательно делает мой код более легким для чтения (для меня в любом случае).

0

Я начну с предупреждения о преждевременной оптимизации производительности. Сосредоточьтесь на читаемости.

Говоря об этом, я бы изучил ИЛ, созданный ими. Это скажет вам, сколько операций требуется каждый.

Я никогда не был системным программистом, поэтому я никогда не вникал в настройку производительности уровня процессора.

0

Не должно быть разницы в производительности между ними.

Сначала попробуйте поместить дешевые сравнения, когда вы связываете их с && или ||. Из-за короткого замыкания ваша программа не будет оценивать правую сторону оператора, если левая сторона уже определяет результат (это тоже полезно в других случаях).

Сравнение ссылок намного проще для компьютера, чем, например, управление строками. Как вы уже сказали, наиболее вероятным может оказаться случай, который чаще всего может быть полезен.

Однако, если это вообще возможно, постарайтесь не испортить читаемость во время оптимизации. Жесткая читаемость для микро-оптимизации трудно оправдать.

Пример:

if (myString != null && myString.ToUpper() == "FOO")
{
    // This works because of short circuiting.
    // myString.ToUpper() will never be evaluated if myString is null.
}
-1

Когда я начинаю думать о чем-то подобном в своем коде, я вспоминаю строку из книги Роберта Гласса "Факты и ошибки разработки программного обеспечения"

"Эффективность больше связана с хорошим дизайном, чем с хорошим кодированием".

Джефф сделал запись в этой книге, в которой перечислены факты и фразы: http://www.codinghorror.com/blog/archives/001083.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню