Will my compiler ignore useless code?

前端 未结 9 1302
情深已故
情深已故 2021-02-06 21:53

I\'ve been through a few questions over the network about this subject but I didn\'t find any answer for my question, or it\'s for another language or it doesn\'t answer totally

相关标签:
9条回答
  • 2021-02-06 22:00

    It won't be ignored. However, when you get to IL there will be a jump statement, so the for will run as if it was an if statement. It will also run the code for ++ and length, as @Fleve mentioned. It will just be extra code. For readability sake, as well as to keep with code standards I would remove the code if you don't use it.

    0 讨论(0)
  • 2021-02-06 22:07

    Well, your variables i and prevSpec_OilCons, if not used anywhere will be optimized away, but not your loop.

    So if your code looks like:

    static void Main(string[] args)
    {
        int[] TestRunTime = { 1, 2, 3 };
        int i = 0;
        for (int j = 0; j < TestRunTime.Length; j++)
        {
    
        }
        double prevSpec_OilCons = 0;
        Console.WriteLine("Code end");
    }
    

    under ILSpy it will be:

    private static void Main(string[] args)
    {
        int[] TestRunTime = new int[]
        {
            1,
            2,
            3
        };
        for (int i = 0; i < TestRunTime.Length; i++)
        {
        }
        Console.WriteLine("Code end");
    }
    

    Since the loop has couple of statements, like comparison and increment, it could be used for implementing somewhat short delay/wait period. (although not a good practice to do so).

    Consider the following loop, which is an empty loop, but it will take a lot of time to get executed.

    for (long j = 0; j < long.MaxValue; j++)
    {
    
    }
    

    The loop in your code, is not a dead code, as far as dead code is concerned, the following is a dead code, and will be optimized away.

    if (false)
    {
        Console.Write("Shouldn't be here");
    }
    

    The loop, will not even be removed by the .NET jitters. Based on this answer

    0 讨论(0)
  • 2021-02-06 22:07

    In your loop there are two an operation implicit in each iteration. An increment:

    j++;
    

    and comparison

    j<TestRunTime.Length;
    

    So, the loop is not empty although it looks like it is. There is something being executed at the end and this is not ignored by the compiler of course.

    This happens also in other loops.

    0 讨论(0)
  • 2021-02-06 22:08

    The loop can't be removed, the code is not dead, for instance:

      // Just some function, right?
      private static Double[] SomeFunctionThatReturnDoubles() {
        return null;
      }
    
      ...
      double[] TestRunTime = SomeFunctionThatReturnDoubles();
      ...
      // You'll end up with exception since TestRunTime is null
      for (int j = 0; j < TestRunTime.Length; j++)
      {
      }
      ...
    

    Usually, compiler just can't predict all possible outcomes of SomeFunctionThatReturnDoubles and that's why it preserves the loop

    0 讨论(0)
  • 2021-02-06 22:12

    Obviously your compiler will not ignore useless code, but analyse it carefully and then try to remove it, if it performs optimisations.

    In your case, the first interesting thing is whether the variable j is used after the loop or not. The other interesting thing is TestRunTime.Length. The compiler will look at it and check whether it always returns the same result, and if yes whether it has any side effects, and if yes whether calling it once has the same side effect in total as calling it repeatedly.

    If TestRunTime.Length has no side effect and j is not used then the loop is removed.

    Otherwise, if calling TestRunTime.Length repeatedly has more side effects than calling it once, or if repeated calls return different values, then the loop must be executed.

    Otherwise, j = max (0, TestRunTime.Length).

    Next, the compiler can determine whether the assignment TestRunTime.Length is needed. It may be replaced with code that just determines what TestRunTime.Length would be.

    Then of course your compiler might not try any fancy optimisations, or the language rules might be so that it cannot determine these things, and you are stuck.

    0 讨论(0)
  • 2021-02-06 22:13

    The JIT is basically capable of removing dead code. It is not very thorough. Dead variables and expressions are reliably killed. That is an easy optimization in SSA form.

    Not sure about control flow. If you nest two loops only the inner one will be deleted I remember.

    If you want to find out for sure what is deleted and what not look at the generated x86 code. The C# compiler does very few optimizations. The JIT does a few.

    The 4.5 32 and 64 bit JITs are different code bases and have different behavior. A new JIT (RyuJIT) is upcoming that in my testing generally does worse, sometimes better.

    0 讨论(0)
提交回复
热议问题