我曾经是Windows上的C++程序员。
我知道编译器将优化C++中的三元运算符。
C++代码:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int result = argc > 3 ? 1 : 5;
printf("%d", result);
return 0;
}
由于管道的原因,生成的 native 代码如下所示(当然是版本模型):
int result = argc > 3 ? 1 : 5;
00B21003 xor eax,eax
00B21005 cmp dword ptr [argc],3
00B21009 setle al
00B2100C lea eax,[eax*4+1]
C#代码:
namespace TernaryOperatorCSharp
{
static void Main(string[] args)
{
int argc = args.Length;
int result = argc > 1 ? 2 : 5;
System.Console.WriteLine(result);
}
}
我查找了JIT生成的 native 代码,但是根本没有优化(还有两个跳转指令)。
int result = argc > 1 ? 2 : 5;
0000002f cmp dword ptr [ebp-4],1
00000033 jg 0000003F
00000035 nop
00000036 mov dword ptr [ebp-0Ch],5
0000003d jmp 00000046
0000003f mov dword ptr [ebp-0Ch],2
00000046 mov eax,dword ptr [ebp-0Ch]
00000049 mov dword ptr [ebp-8],eax
System.Console.WriteLine(result);
0000004c mov ecx,dword ptr [ebp-8]
0000004f call 6A423CBC
为什么C#JIT编译器不进行与C++编译器相同的优化?
这背后的故事是什么?
任何信息将不胜感激。
嗨,您好,
我已经修改了C#程序,并使用发布模型运行它。
之前
int result = args.Length > 1 ? 2 : 5;
现在
int argc = args.Length;
int result = argc > 1 ? 2 : 5;
但是结果仍然是一样的。
仍然存在两个跳转指令。
如果有更多详细信息,我们将不胜感激。
最佳答案
您没有在进行优化编译-nop
指令指示了这一点(编译器将其插入以用作 anchor ,以便可以在大括号上放置断点)。
即使选中了“优化代码”复选框,Visual Studio也不总是产生优化的代码。通常,当您在调试器中启动时,它会始终禁用优化,因此调试 session 的行为会超出您的预期。
此外,您没有将苹果与苹果进行比较,因为苹果占了大部分。string[].Length
是C#中的属性,不是公共(public)变量,而且不是局部变量。通过使用代码,通常将属性视为公共(public)变量,但实际上,它们可以作为成熟的get/set方法存在。编译器必须发出代码来处理此问题,尤其是在单独的程序集中定义了Property的情况下。
尝试使用本地int
变量并打开编译器优化的示例(使用优化进行构建,启动程序,在启动后附加调试器,查看反汇编)。
关于c# - C#与C++三元运算符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20827111/