code4Better Ответов: 4

Различные способы проверки null в C#


Привет,
Вопрос касается 2 различных способов проверки null, которые были сделаны в C#

1: if (object = = null)

2: if (null = = object)

мало кто говорит, что есть улучшения производительности, когда мы используем 2: например, компилятору будет легко конвертировать код. Но я не уверен, что эта информация верна. Обычно я предпочитаю 1:

Есть ли веская причина использовать 2:??

С уважением

Что я уже пробовал:

Попробовал оба способа и обнаружил, что оба прекрасно работают для меня

Ralf Meier

Я также предпочитаю версию 1-потому что мой код каждый раз пишется как "переменная" и "для сравнения".

code4Better

Но есть ли между ними какая-то разница ...

Richard MacCutchan

Нет никакой разницы, так как объектный код будет одинаковым, сравните переменную с константой. Второй пример, используемый, чтобы быть рекомендуемый, чтобы избежать ошибок, таких как
if (object = null)
но большинство, если не все, компиляторы предупредят вас о возможных побочных эффектах такого утверждения.

Rob Philpott

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

Richard MacCutchan

Что ж, для меня это впервые. :)

4 Ответов

Рейтинг:
20

Karthik_Mahalingam

Цитата:
мало кто говорит, что есть улучшения производительности, когда мы используем 2

Да вот доказательство
случайным образом запустил следующий код в течение 5 раз и результаты как показано ниже


obj = = null
object obj = null;
     System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
     watch.Start();
     if (obj == null) { }
     watch.Stop();
     var a = watch.Elapsed.Ticks;

null = = obj1
object obj1 = null;
            System.Diagnostics.Stopwatch watch1 = new System.Diagnostics.Stopwatch();
            watch1.Start();
            if (null == obj1) { }
            watch1.Stop();
            var b = watch1.Elapsed.Ticks;


Результат
Прошло Клещей
obj = = null null = = obj1
37 0
32 2
27 0
135 18
37 9


0x01AA

5 за усилия(надеюсь, вы пробежали его достаточно раз). Может быть, это также узнаваемо в коде IL?

Karthik_Mahalingam

Спасибо 0x01AA

ZurdoDev

+5

Karthik_Mahalingam

Спасибо Ряндев

Ralf Meier

Извините... Я не согласен с вами (на этот раз).
Пожалуйста, взгляните на мое решение (4)

Рейтинг:
1

Ralf Meier

В основном я согласен с Ричардом и Йохеном.
Из-за результатов Karthik я сделал свой собственный тест, потому что я не мог поверить в эти результаты.

Я проверил его с помощью VB.Net, а также с помощью C#.Сеть с этим кодом-блоки :

Dim myObject As Object = Nothing
Dim x As Boolean

Dim d1 As Date = Now

For i As Integer = 1 To 100000000
    If (myObject Is Nothing) Then x = True
Next

Dim d2 As Date = Now

For i As Integer = 1 To 100000000
    If (Nothing Is myObject) Then x = True
Next

Dim d3 As Date = Now

Dim ts1 As TimeSpan = d2 - d1
Dim ts2 As TimeSpan = d3 - d2


object myObject = null ;
bool x = false;

System.DateTime d1 = System.DateTime.Now;

for (int i = 1; i <= 100000000; i++)
{
    if ((myObject == null))
        x = true;
}

System.DateTime d2 = System.DateTime.Now;

for (int i = 1; i <= 100000000; i++)
{
    if ((null == myObject))
        x = true;
}

System.DateTime d3 = System.DateTime.Now;

TimeSpan ts1 = d2 - d1;
TimeSpan ts2 = d3 - d2;


Вот мои результаты (сделав сравнение 100 миллионов раз :

Сравниваем период с VB период с#
myObj (присвоено) Nothing / Null 0,2390137 секунды 0,2808005 секунды
Nothing / Null to myObj (assigned) 0,3090174 секунды 0,2808006 секунды
myObj (not assigned) to Nothing / Null 0,3588006 секунды 0,3900007 секунды
Nothing / Null to myObj (not assigned) 0,2962005 секунды 0,2744006 секунды

Инт-постоянное целое число-переменная 0,2652005 секунд 0,2652005 секунд
Int-переменная в целое число-Константа 0,2652005 секунды 0,2652005 секунды

Я думаю, что в среднем более 100 миллионов циклов говорят гораздо больше, чем только 1 цикл-тест (извините, Картик), который показывает разные значения с большим диапазоном.
Но для меня также было очень интересно, что существует разница (по обработке объектов) между VB и C# ...


Karthik_Mahalingam

я запустил тот же код
тем не менее есть разница в 100 + миллисекунд

попробуйте этот код

  object myObject = null;


        System.Diagnostics.Stopwatch watch1 = new System.Diagnostics.Stopwatch();
        watch1.Start();


        for (int i = 1; i <= 100000000; i++)
        {
            if (null == myObject) { }

        }
        watch1.Stop();


        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
        watch.Start();

        for (int i = 1; i <= 100000000; i++)
        {
            if (myObject == null){}
               
        }
        watch.Stop();

      
        var a = watch.Elapsed.TotalMilliseconds;
        var b = watch1.Elapsed.TotalMilliseconds;

Ralf Meier

(может быть) мой компьютер не самый производительный одна ... :(
Но для меня было важно увидеть процентную зависимость ...

Рейтинг:
0

Jochen Arndt

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

[EDIT2]
Я был слишком связан с C/C++ и забыл, что условия должны оцениваться в a bool.
[/EDIT2]
Но вторая форма имеет преимущество, если вы по ошибке набираете только один знак равенства:

// Assigns null to object, condition is always false
if (object = null)
{
}
// Compiler error
if (null = object)
{
}

[РЕДАКТИРОВАТЬ]
Использование object и null это не самый лучший пример здесь.

Это имеет больше смысла для интегральных типов, таких как int:
if (0 = num)

Однако это также должно генерировать предупреждение о состоянии, которое всегда является ложным.
[/РЕДАКТИРОВАТЬ]


Richard MacCutchan

Первый пример вызывает предупреждение в VS.

0x01AA

Я думаю, что это закончится ошибкой для c# "не может неявно преобразовать tyoe 'object' в 'bool'

Richard MacCutchan

Именно так.

code4Better

Да, вы правы. Он скажет, что не может неявно преобразовать тип object в bool.

F-ES Sitecore

Да, это то, что вы увидите только в старом коде, это была привычка кодирования, которую люди пытались использовать на случай, если у них была опечатка кода при сравнении\присвоении. В наши дни это не распространено, поскольку современные компиляторы и IDE настолько быстры и мощны, что проблема будет решена довольно быстро. Однако в те дни компиляция большого приложения занимала 10 минут, поэтому все, что вы могли сделать, чтобы отметить ошибки во время компиляции, было хорошо.

0x01AA

Нет, также ваша отредактированная версия не корректна для c# (для которого помечен Q).

int num= 0;
если (0 = num) / /- & gt; левая часть присваивания должна быть переменной...
;

if (num = 0) / / - > Не может неявно преобразовать тип 'int' в 'bool'
;

Jochen Arndt

Вы правы.
Я слишком сильно ориентируюсь на C/C++.

0x01AA

Я больше всего времени провожу с c++ и очень рад, что в c# Эта ловушка исчезла :)

Рейтинг:
0

ZurdoDev

Насколько я понимаю, у второго действительно есть небольшое улучшение производительности. Что-то о том, что нужно только увидеть, является ли второй объект нулевым или нет, а не первый способ, которым он должен загрузить фактический объект, а затем сравнить его с нулем.

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