Joh*_*lph 11 c# compiler-construction optimization
我刚才注意到给出以下代码:
if (x.ID > 0 && !x.IsCool)
Run Code Online (Sandbox Code Playgroud)
Microsoft C#3.0(VS2008 SP1)编译器将优化它:
if (!((x.Id <= 0) || x. IsCool))
Run Code Online (Sandbox Code Playgroud)
这是在未启用优化的Debug构建中.为什么编译器会这样做?它在执行方面更快吗?
我用Reflector找到了(我实际上是在寻找不同的东西)
Meh*_*ari 49
C#编译器肯定不会为您的代码段生成等效的C#代码.它编译成IL.基本上,你所看到的(来自Reflector,我猜)是反编译器为该IL吐出的等效C#代码.
语言规范没有说明"未经优化"的代码是什么.允许C#编译器生成任何有效的,功能相同的代码.即使没有优化开关,编译器也可以进行基本优化.除了这一点,你不能说什么是自然的编译器和是否编译器优化故意与否.
整个if语句根据"and"子句中指定的每个单独表达式的值计算为一系列条件分支.不使用"和"指令在单个代码块中计算表达式.反编译器的输出是从这些分支推断出来的.反编译器不能总是推断你写的原始表达式.它只输出相当的东西.
同样,这个片段之间的区别:
if (a) { something(); }
else { somethingElse(); }
Run Code Online (Sandbox Code Playgroud)
这个片段:
if (!a) { somethingElse(); }
else { something(); }
Run Code Online (Sandbox Code Playgroud)
通过查看已编译的代码,您无法区分.
我认为从语义语义的角度来看,这两个表达式完全相同.两种方式都涉及短路.
我有点大吃一惊,安德鲁的回答已经有十个赞成票; 这听起来像是胡说八道,但也许我真的错过了一些微妙的东西.
编辑
所以总结一下:
OP的问题是"为什么这种优化会发生".
事实上,没有"优化"发生.两个C#源代码在逻辑上是等价的.".Net Reflector"或其他任何反汇编工具也许可能将同一个IL反编译成一个或另一个.在IL级别,只有一堆条件跳转,所以没有必要知道"哪种方式是哪种方式,哪种方式是其他方式"或其他类似的DeMorgan等价方式.
令人着迷的是,人们非常乐意对这个问题的答案进行评论,即使(或者可能是因为)原始问题没有多大意义(或依赖于错误的假设).
令人高兴的是,最终人群的智慧(以及像@Mehrdad这样聪明的人)占上风.欢迎来到StackOverflow!
(我正在回答一个wiki,因为当代表被授予"问题的好答案"时,我不希望代表"讲述一个问题的故事".但我认为这个问题的故事很有趣.)