简单的 Add 方法产生过多的 IL 代码
Simple Add method produces too much IL code
我正在尝试使用 IL 代码改进我的 C# 数学运算。目前的一个问题是 C# 不允许对泛型进行数学运算,但 IL 允许——至少对于原始数据类型(有趣的是不是十进制)。出于这个原因,我在 C# 中创建了一些测试方法来检查生成的 IL 代码。
这是 C# 方法的代码:
public static float Add(float A, float B)
{
return A + B;
}
这是打开 VS2015SP2 / 发布 + 优化的结果。
只是为了确保:这是构建中的 csc 命令行:
C:\Program Files (x86)\MSBuild.0\bin\csc.exe /noconfig
/nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu32bitpreferred
/errorreport:prompt /warn:4 /define:TRACE /errorendlocation
/preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files
(x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\Microsoft.CSharp.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\mscorlib.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Core.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.DataSetExtensions.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Net.Http.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.dll"
/reference:"C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.Linq.dll"
/debug- /filealign:512 /optimize+
/out:obj\Release\ConsoleApplication1.exe /ruleset:"C:\Program Files
(x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis
Tools\Rule Sets\MinimumRecommendedRules.ruleset"
/subsystemversion:6.00 /target:exe /utf8output Program.cs
Properties\AssemblyInfo.cs
"C:\Users\Martin\AppData\Local\Temp.NETFramework,Version=v4.5.2.AssemblyAttributes.cs"
obj\Release\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs
obj\Release\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs
obj\Release\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs
(TaskId:27) 1>
.method public hidebysig static
float32 Add (
float32 A,
float32 B
) cil managed
{
// Method begins at RVA 0x2054
// Code size 9 (0x9)
.maxstack 2
.locals init (
[0] float32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
} // end of method Program::Add
你知道为什么里面仍然有 nop,为什么有一个局部变量,为什么最后有一个什么都不做的跳转吗?
我很清楚最终的抖动可能会解决这个问题,但如果我看到这个我不知道,如果我可以相信抖动。
谢谢
马丁
恐怕我不能重复你的结果。使用 csc /debug- /optimize+ 编译然后使用 ildasm,我得到:
.method public hidebysig static float32 Add(float32 A,
float32 B) cil managed
{
// Code size 4 (0x4)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: add
IL_0003: ret
} // end of method Program::Add
这是我对优化代码的期望。事实上,如果我更改为优化-,我会得到您发布的代码。您是否正在检查 Debug 与 Release 子目录?
我正在尝试使用 IL 代码改进我的 C# 数学运算。目前的一个问题是 C# 不允许对泛型进行数学运算,但 IL 允许——至少对于原始数据类型(有趣的是不是十进制)。出于这个原因,我在 C# 中创建了一些测试方法来检查生成的 IL 代码。 这是 C# 方法的代码:
public static float Add(float A, float B)
{
return A + B;
}
这是打开 VS2015SP2 / 发布 + 优化的结果。 只是为了确保:这是构建中的 csc 命令行:
C:\Program Files (x86)\MSBuild.0\bin\csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu32bitpreferred /errorreport:prompt /warn:4 /define:TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Net.Http.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.Linq.dll" /debug- /filealign:512 /optimize+ /out:obj\Release\ConsoleApplication1.exe /ruleset:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\MinimumRecommendedRules.ruleset" /subsystemversion:6.00 /target:exe /utf8output Program.cs Properties\AssemblyInfo.cs "C:\Users\Martin\AppData\Local\Temp.NETFramework,Version=v4.5.2.AssemblyAttributes.cs" obj\Release\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs obj\Release\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs obj\Release\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs (TaskId:27) 1>
.method public hidebysig static
float32 Add (
float32 A,
float32 B
) cil managed
{
// Method begins at RVA 0x2054
// Code size 9 (0x9)
.maxstack 2
.locals init (
[0] float32
)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: stloc.0
IL_0005: br.s IL_0007
IL_0007: ldloc.0
IL_0008: ret
} // end of method Program::Add
你知道为什么里面仍然有 nop,为什么有一个局部变量,为什么最后有一个什么都不做的跳转吗?
我很清楚最终的抖动可能会解决这个问题,但如果我看到这个我不知道,如果我可以相信抖动。
谢谢 马丁
恐怕我不能重复你的结果。使用 csc /debug- /optimize+ 编译然后使用 ildasm,我得到:
.method public hidebysig static float32 Add(float32 A,
float32 B) cil managed
{
// Code size 4 (0x4)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: add
IL_0003: ret
} // end of method Program::Add
这是我对优化代码的期望。事实上,如果我更改为优化-,我会得到您发布的代码。您是否正在检查 Debug 与 Release 子目录?