【问题标题】:C# Optimisation Combining Return StatementsC# 优化组合返回语句
【发布时间】:2019-11-14 01:14:05
【问题描述】:

我使用 Visual Studio 在 C# 中编写了一个函数,并决定查看在启用“优化代码”构建标志的情况下编译时的样子。

我用 dnSpy 检查了 DLL,发现 if 语句已被删除。这导致每次调用函数时都会访问 neighbour.data 数组,这是我试图避免的。

这是 Visual Studio 中的函数:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool DrawFaceXNegative(int j, int k, int chunkPosition, Chunk neighbour)
{
    // These two if statements are here to prevent an array access if possible
    if (chunkPosition == 0)
        return false;

    if (neighbour == null)
        return true;

    return neighbour.data[31 * Constants.ChunkSize + j + k * Constants.ChunkSizeSquared].index == 0;
}

这是dnSpy中的函数:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool DrawFaceXNegative(int j, int k, int chunkPosition, Chunk neighbour)
{
    return chunkPosition != 0 && (neighbour == null || neighbour.data[992 + j + k * 1024].index == 0);
}

将逻辑更改为 if-else 语句会产生相同的结果。有没有办法防止这种优化发生?

作为一个附带问题,是什么导致编译器认为生成的函数更加优化?

【问题讨论】:

  • 据我所知,它只是在生成的 IL 字节数方面更优化,性能是相同的。
  • 您能否澄清一下“这导致每次调用函数时都会访问 neighbour.data 数组”?正如@BradleySmith 所说,代码是完全一样的,反编译器可能只是进行了 IL->C# 转换,而不是您喜欢的方式。比较“优化”的 IL 和方法的调试版本以确认。
  • 您的代码使用chunkPosX 而不是chunkPosition。我认为这是一个复制错误
  • "...这导致每次调用该函数时都会访问 neighbour.data 数组..." - 是什么让您这么认为?仅当 chunkPosition != 0 && (neighbour == null 时才如此。
  • @MickyD from Christopher's answer我不知道如果条件的第一部分为假,其余的 && 计算将停止。谢谢大家的cmets

标签: c# compilation compiler-optimization


【解决方案1】:
return chunkPosition != 0 && ...

正在做与

完全相同的事情
  if (chunkPosition == 0)
        return false;

在chunkPosition为0的情况下:

  1. 根据 && 规则停止其余的计算
  2. 返回错误

如果这部分的计算结果为 true,则返回值将是 true && (neighbour == null || neighbour.data[992 + j + k * 1024].index == 0); - 所以无论省略号导致什么。

&& 连接的东西被执行,直到你打到第一个 false。

||连接的东西被执行,直到你点击第一个 true。

如果你想让所有代码一直执行,我认为单字符版本就是你要找的机器人。

【讨论】:

  • 谢谢,我不知道 && 规则会导致其余的计算停止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 2012-07-24
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多