【发布时间】: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