Сравнение логических условий

#c# #.net #performance #comparison #logic

#c# #.net #Производительность #сравнение #Логические

Вопрос:

Есть два логических условия :

 A. ( Ls != Ec amp;amp; Ls != Uc amp;amp; Ls != Rfc )

B. (!(Ls==Ec || Ls == Uc || Ls == Rfc))
  

Переменными являются Ls, Ec, Uc, Rfc (целые числа)

Я обнаружил, что оба условия логически одинаковы.

Мой вопрос / ы таков (есть!) :

Существует ли какой-либо онлайн-инструмент / Сеть для проверки нескольких / двух логических условий? И с точки зрения производительности, что лучше в целом или по отношению к C # .NET 3.5

Спасибо.

Комментарии:

1. Вы обнаружили теорему Де Моргана en.wikipedia.org/wiki/Demorgan’s_theorem

2. @ Все, я знаю, что это глупый вопрос, и также не создаю никаких приложений высокого класса, но просто было любопытно узнать, существует ли какая-либо разница в производительности или нет?

Ответ №1:

В Интернете я ничего не знаю, но изучение и применение законов Де Моргана и таблиц истинности помогут вам достичь этого самостоятельно.

Комментарии:

1. отлично, спасибо. И С точки зрения производительности оба не будут иметь ни малейшей разницы?? Верно?

2. @Rahul Joshi — если нет побочных эффектов для различных условий, короткое замыкание может оказать очень незначительное влияние на производительность.

Ответ №2:

Компилятор C #, похоже, генерирует идентичный IL для обоих кодов (как при отладке, так и при сборке релиза). Следовательно, между ними не должно быть разницы в производительности.

На самом деле, согласно IL, компилятор C # переводит TestTwo в testOne. Когда вы видите скомпилированную dll в Reflector, TestTwo становится testOne.

Я скомпилировал следующий код и открыл их в ILDASM.

     public bool TestOne(int l, int e, int u, int r)
    {
        return (l != e amp;amp; l != u amp;amp; l != r);
    }

    public bool TestTwo(int l, int e, int u, int r)
    {
        return (!(l == e || l == u || l == r));
    }
  

Следующее — это то, что я видел в ILDASM (на основе сборки выпуска).

 .method public hidebysig instance bool  TestOne(int32 l,
                                                int32 e,
                                                int32 u,
                                                int32 r) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  beq.s      IL_0011
  IL_0004:  ldarg.1
  IL_0005:  ldarg.3
  IL_0006:  beq.s      IL_0011
  IL_0008:  ldarg.1
  IL_0009:  ldarg.s    r
  IL_000b:  ceq
  IL_000d:  ldc.i4.0
  IL_000e:  ceq
  IL_0010:  ret
  IL_0011:  ldc.i4.0
  IL_0012:  ret
} // end of method Program::TestOne

.method public hidebysig instance bool  TestTwo(int32 l,
                                                int32 e,
                                                int32 u,
                                                int32 r) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  beq.s      IL_0011
  IL_0004:  ldarg.1
  IL_0005:  ldarg.3
  IL_0006:  beq.s      IL_0011
  IL_0008:  ldarg.1
  IL_0009:  ldarg.s    r
  IL_000b:  ceq
  IL_000d:  ldc.i4.0
  IL_000e:  ceq
  IL_0010:  ret
  IL_0011:  ldc.i4.0
  IL_0012:  ret
} // end of method Program::TestTwo
  

Я использовал VS2008 sp1 (.NET 3.5 sp1) для тестирования этого кода.

Ответ №3:

Есть поговорка «Сначала заставь это работать, затем сделай это быстро!». Я бы предположил, что разница (если она вообще существует) между обеими версиями не повлияет на общую производительность вашего приложения — по крайней мере, в 99,99% всех приложений. Если ваше приложение входит в число оставшихся 0,001%, то вы пишете очень особенное и сложное высокоскоростное программное обеспечение. В этом случае вам не следует использовать теоретические инструменты. Измерьте это в реальных условиях!

Ответ №4:

Я считаю, что это зависит от реализации…
На a .Платформа на основе сети, насколько я помню, при использовании оператора amp;amp; выражение вычисляется слева направо, и если левый операнд равен false, правый даже не вычисляется. Исходя из этой логики, я чувствую, что вариант A был бы выбран и быстрее, если бы один из этих самых левых операндов оказался ложным. Я предполагаю, что это может быть причиной, по которой IL generated предпочитает использовать метод testOne (Кстати, отличная идея определить, каков выбранный путь, спасибо Chansik Im.