我的编译器会忽略无用的代码吗?

Tho*_*oub 40 .net c# dead-code compiler-optimization

我已经通过网络问了几个关于这个问题的问题,但我没有找到任何问题的答案,或者它是针对另一种语言的,或者它没有完全回答(死代码不是无用的代码)所以这是我的问题:

编译器是否忽略(显式或非显式)无用代码?

例如,在此代码中:

double[] TestRunTime = SomeFunctionThatReturnDoubles;
// A bit of code skipped
int i = 0;
for (int j = 0; j < TestRunTime.Length; j++)
{

}
double prevSpec_OilCons = 0;
Run Code Online (Sandbox Code Playgroud)

for循环会被删除吗?

我使用


背景是我维护了很多代码(我没有写),我想知道无用的代码是否应该是目标,或者我是否可以让编译器处理它.

Hab*_*bib 27

好吧, 你的变量iprevSpec_OilCons,如果不在任何地方使用,将被优化掉,但不是你的循环.

所以,如果您的代码如下:

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");
}
Run Code Online (Sandbox Code Playgroud)

ILSpy下它将是:

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");
}
Run Code Online (Sandbox Code Playgroud)

由于循环具有几个语句,如比较和增量,因此可用于实现稍短的延迟/等待时间. (虽然不是一个很好的做法).

考虑以下循环,这是一个空循环,但它将花费大量时间来执行.

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

}
Run Code Online (Sandbox Code Playgroud)

代码中的循环不是死代码,就死代码而言,以下是死代码,并且将被优化掉.

if (false)
{
    Console.Write("Shouldn't be here");
}
Run Code Online (Sandbox Code Playgroud)

这个循环甚至不会被.NET抖动删除.基于这个答案

  • "......它可以用来实现稍微短的延迟/等待时间......"如果执行时间是一个理想的特性,编译器就不会允许性能优化. (8认同)
  • @Panzercrisis,它就在那里,我可以在ILSpy中看到. (3认同)

Dmi*_*nko 15

循环无法删除,代码没有死,例如:

  // 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++)
  {
  }
  ...
Run Code Online (Sandbox Code Playgroud)

通常,编译器无法预测所有可能的结果,SomeFunctionThatReturnDoubles这就是它保留循环的原因

  • @supercat那不一样.你不可能知道Length属性什么都不做.例如,如果长度跟踪在返回结果之前调用get {}的次数,则优化将与实际预期的不同.编译器必须绝对确定在优化之前没有副作用. (2认同)

Fle*_*eve 6

在循环中,每次迭代都隐含两个操作.增量:

j++;
Run Code Online (Sandbox Code Playgroud)

和比较

j<TestRunTime.Length;
Run Code Online (Sandbox Code Playgroud)

所以,虽然它看起来像是循环,但它不是空的.最后会有一些东西被执行,编译器当然不会忽略它.

这也发生在其他循环中.


Tho*_*oub 1

我根据一些回答者关于使用的想法制作了一个小表格来测试它long.MaxValue,这是我的参考代码:

public Form1()
{
    InitializeComponent();
    Stopwatch test = new Stopwatch();
    test.Start();
    myTextBox.Text = test.Elapsed.ToString();
}
Run Code Online (Sandbox Code Playgroud)

这是带有一些无用代码的代码:

public Form1()
{
    InitializeComponent();
    Stopwatch test = new Stopwatch();
    test.Start();
    for (int i = 0; i < int.MaxValue; i++)
    {
    }
    myTextBox.Text = test.Elapsed.ToString();
}
Run Code Online (Sandbox Code Playgroud)

你会说我用的是 ,int.MaxValue而不是 ,long.MaxValue我不想在这个上花费一年的时间。

如你看到的:

---------------------------------------------------------------------
|                   |   Debug               |   Release             |
---------------------------------------------------------------------
|Ref                |   00:00:00.0000019    |   00:00:00.0000019    |
|Useless code       |   00:00:05.3837568    |   00:00:05.2728447    |
---------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

代码没有优化。稍等一下,我会尝试一些int[]测试int[].Lenght

public Form1()
{
    InitializeComponent();
    int[] myTab = functionThatReturnInts(1);

    Stopwatch test = new Stopwatch();
    test.Start();
    for (int i = 0; i < myTab.Length; i++)
    {

    }
    myTextBox.Text = test.Elapsed.ToString();
}
public int[] functionThatReturnInts(int desiredSize)
{
    return Enumerable.Repeat(42, desiredSize).ToArray();
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

---------------------------------------------
|   Size            |   Release             |
---------------------------------------------
|             1     |   00:00:00.0000015    |
|           100     |   00:00:00            |
|        10 000     |   00:00:00.0000035    |
|     1 000 000     |   00:00:00.0003236    |
|   100 000 000     |   00:00:00.0312673    |
---------------------------------------------
Run Code Online (Sandbox Code Playgroud)

因此,即使使用数组,它也根本没有得到优化。