c # IF оптимизация производительности - PullRequest
0 голосов
/ 03 июля 2018

Какой метод быстрее для миллионов циклов?

двойной a, b, c, d, e, f;

1

for (int i=0; i<1000000; i++)
{
  // simulation which changes the a,b,c,d,e,f values
  ...
  if (a>b)
  {
     if (c<d)
     {
       if (e==f)
         // do something
     }
  }
}

2.

for (int i=0; i<1000000; i++)
{
   // simulation which changes the a,b,c,d,e,f values
   ...
   if ((a>b) && (c<d) && (e==f))
     // do something
}

Я думал, что метод 1 будет быстрее, потому что он пропускает много раз при сравнении вместо сравнения всех трех переменных одновременно.

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Это (вероятно) абсолютно нереалистичный тест, но здесь вы идете

Тесты

Mode             : Release (64Bit)
Test Framework   : .NET Framework 4.7.1

Operating System : Microsoft Windows 10 Pro
Version          : 10.0.17134

CPU Name         : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
Description      : Intel64 Family 6 Model 42 Stepping 7

Cores (Threads)  : 4 (8)      : Architecture  : x64
Clock Speed      : 3401 MHz   : Bus Speed     : 100 MHz
L2Cache          : 1 MB       : L3Cache       : 8 MB

Benchmarks Runs : Inputs (1) * Scales (1) * Benchmarks (3) * Runs (1000) = 3,000

Результаты

--- Standard input --------------------------------------------------------
| Value  |   Average |   Fastest |     Cycles |  Garbage | Test |    Gain |
--- Scale 1,000,000 --------------------------------------- Time 28.630 ---
| Bit    |  9.120 ms |  8.332 ms | 31,041,747 | 7.477 KB | N/A  | 37.59 % |
| Single | 14.549 ms | 13.815 ms | 49,549,071 | 7.541 KB | N/A  |  0.45 % |
| Multi  | 14.615 ms | 13.806 ms | 49,730,909 | 7.545 KB | Base |  0.00 % |
---------------------------------------------------------------------------

Данные испытаний

private List<Tuple<double, double, double, double, double, double>> GenerateInput(int scale)
{
   var list = Enumerable.Range(0, scale)
                        .Select(x => new Tuple<double, double, double, double, double, double>(Rand.Next(), Rand.Next(), Rand.Next(), Rand.Next(), Rand.Next(), Rand.Next()))
                        .ToList();
   return list;
}

Multi

public class Multi : Benchmark<List<Tuple<double, double, double, double, double, double>>, int>
{
   protected override int InternalRun()
   {
      int i = 0;
      foreach (var item in Input)
         if (item.Item1 > item.Item2)
            if (item.Item3 < item.Item4)
               if (item.Item5 == item.Item6)
                  i++;

      return i;
   }    
}

Single

public class Single : Benchmark<List<Tuple<double, double, double, double, double, double>>, int>
{
   protected override int InternalRun()
   {
      int i = 0;
      foreach (var item in Input)
         if ((item.Item1 > item.Item2) && (item.Item3 < item.Item4) && (item.Item5 == item.Item6))
            i++;

      return i;
   }
}

Бит

public class Bit : Benchmark<List<Tuple<double, double, double, double, double, double>>, int>
{
   protected override int InternalRun()
   {
      int i = 0;
      foreach (var item in Input)
         if ((item.Item1 > item.Item2) & (item.Item3 < item.Item4) & (item.Item5 == item.Item6))
            i++;

      return i;
   } 
}
0 голосов
/ 03 июля 2018

Вы не правы. Оператор C # && использует то, что называется оценка короткого замыкания .

Проще говоря, при оценке a && b, если a равно false, компьютер не будет беспокоиться о оценке b.

Оба фрагмента должны работать одинаково.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...