代码之家  ›  专栏  ›  技术社区  ›  Johannes Rudolph

编译器魔法:为什么?

  •  11
  • Johannes Rudolph  · 技术社区  · 16 年前

    if (x.ID > 0 && !x.IsCool)
    

    Microsoft C#3.0(VS2008 SP1)编译器将对其进行以下优化:

    if (!((x.Id <= 0) || x. IsCool))
    

    这是调试版本 已启用优化。为什么编译器会这样做?执行速度快吗?

    3 回复  |  直到 16 年前
        1
  •  49
  •   Mehrdad Afshari    16 年前

    C#编译器当然是 . 它被编译成IL。基本上,你所看到的(我想是从Reflector上看到的)是一个 反编译器 为那个IL吐口水。

    1. 语言规范没有说明什么是“未优化”代码。C#编译器可以生成任何有效的、功能等效的代码。即使没有打开优化开关,编译器也可能进行基本优化。除此之外,你不能说 是什么 对于编译器

    2. if 语句作为一个整体,根据“and”子句中指定的每个表达式的值,作为一系列条件分支进行计算。表达式是 不

    同样,此代码段之间的区别:

    if (a) { something(); }
    else { somethingElse(); }
    

    这段话:

    if (!a) { somethingElse(); }
    else { something(); }
    

        2
  •  8
  •   Brian    16 年前

    我认为从语言语义学的角度来看,这两个表达式是完全等价的。这两种方法都涉及短路。

    编辑

    总而言之:

    OP的问题是“为什么会发生这种优化”。

    事实上,没有“优化”发生。这两个C#源代码在逻辑上是等价的。“.Net Reflector”或任何其他反汇编工具可能同样可能将相同的IL反编译为一个或另一个。在IL层面上,只存在一系列条件跳跃,因此不一定有办法知道“哪条路是if,哪条路是else”或其他类似的DeMorgan等价物。

    令人高兴的是,最终群众(以及@Mehrdad这样的聪明人)的智慧占了上风。万岁!

    (我把我的答案做成了一个维基,因为我不想让rep因为“讲述一个问题”而被授予“一个问题的好答案”。但我认为这个问题的故事很有趣。)

        3
  •  6
  •   Ants Aasma    16 年前

    if编译为条件跳转操作码。通过将条件跳转目标与fall-through块交换,将否定从表达式中取出,可以对其进行优化。