首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#与C++三值算子

C#与C++三值算子
EN

Stack Overflow用户
提问于 2013-12-29 16:06:56
回答 2查看 598关注 0票数 13

我以前是Windows上的C++程序员。我知道编译器将优化C++中的三元操作符。

C++代码:

代码语言:javascript
运行
复制
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
    int result = argc > 3 ? 1 : 5;
    printf("%d", result);
    return 0;
}

由于管道的原因,生成的本机代码如下所示(当然,发布模型):

代码语言:javascript
运行
复制
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#代码:

代码语言:javascript
运行
复制
namespace TernaryOperatorCSharp
{
    static void Main(string[] args)
    {
        int argc = args.Length;
        int result = argc > 1 ? 2 : 5;
        System.Console.WriteLine(result);
    }
}

我查找了生成的本机代码JIT,但是根本没有优化(仍然有两个跳转指令)。

代码语言:javascript
运行
复制
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#程序,并使用发布模型运行它。

先于

代码语言:javascript
运行
复制
int result = args.Length > 1 ? 2 : 5;

Now

代码语言:javascript
运行
复制
int argc = args.Length;
int result = argc > 1 ? 2 : 5;

但结果还是一样的。还有两个跳转指令。如果还有更多的信息,我将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-29 18:36:05

您不是在进行优化编译-- nop指令说明了这一点(编译器将这些指令作为锚点插入,以便在大括号上放置断点)。

即使选中了“优化代码”复选框,Visual也不会总是生成优化代码。通常,当您在调试器中启动时,它无论如何都会禁用优化,这样调试会话就会像您预期的那样表现得更好。

此外,你不能把苹果和苹果作比较,因为苹果占了更多的便宜。

string[].Length是C#中的属性,不是公共变量,而且也不是局部变量。通过使用代码,属性通常被视为公共变量,但实际上可以作为完整的get/set方法存在。编译器必须发出代码来处理这个问题,特别是当属性在单独的程序集中定义时。

使用本地int变量尝试这个示例,并打开编译器优化(使用优化构建、启动程序、在启动后附加调试器、查看反汇编)。

票数 11
EN

Stack Overflow用户

发布于 2013-12-29 19:05:53

您正在查看程序的Debug构建。切换到发布版本。

您必须更改一个选项,以便在使用调试器查看反汇编时不会禁用优化器。工具+选项,调试,一般,取消“抑制JIT优化对模块加载”选项。

现在您将看到更紧凑的代码。x86抖动确实执行分支消除,并使用AGU作为数学,您可以看到它是在this answer中完成的,只是不在这里。如果您期望与C或C++编译器的优化器完全一致,那么抖动优化器将在相当严格的时间限制下运行,因为它在运行时运行。您将看到它在this answer中执行的优化大纲。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20827111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档