代码之家  ›  专栏  ›  技术社区  ›  Mario

c如果性能优化

  •  -2
  • Mario  · 技术社区  · 7 年前

    哪种方法对于数百万个循环更快?

    双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会更快,因为它跳过了许多比较,而不是每次都同时比较所有3个变量。

    2 回复  |  直到 7 年前
        1
  •  2
  •   TheGeneral    7 年前

    这(可能)是一个完全不切实际的测试,但现在开始吧。

    基准

    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;
    }
    

    多个

    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;
       }    
    }
    

    单一的

    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;
       } 
    }
    
        2
  •  2
  •   Tim Schmelter    7 年前

    你错了。C氏 && operator 使用一种叫做 short-circuit evaluation .

    显然,在评估时 a && b 如果 a false 计算机不会费心评估 b .

    两个代码段的性能应该相同。

    推荐文章