【问题标题】:Comparing Logical Conditions比较逻辑条件
【发布时间】:2011-04-13 16:06:08
【问题描述】:

有两个逻辑条件:

A. ( Ls != Ec && Ls != Uc && Ls != Rfc )

B. (!(Ls==Ec || Ls == Uc || Ls == Rfc))

变量有Ls、Ec、Uc、Rfc(整数)

我发现这两个条件在逻辑上是相同的。

我的问题是(是!):

是否有任何在线工具/网络来检查多个/两个逻辑条件? 在性能方面,这通常更好或相对于 C# .NET 3.5

谢谢。

【问题讨论】:

标签: c# .net performance comparison logic


【解决方案1】:

我不知道在线上的任何内容,但学习和应用 De Morgan's LawsTruth Tables 会让你自己到达那里。

【讨论】:

  • 很好,谢谢。 &就性能而言,两者甚至都没有丝毫差异??对吧?
  • @Rahul Joshi - 如果对不同条件没有副作用,短路可能会对性能产生非常轻微的影响。
【解决方案2】:

C# 编译器似乎为两种代码生成了相同的 IL(包括调试和发布版本)。因此,两者之间必须没有性能差异。

事实上,根据IL,C#编译器将TestTwo翻译成TestOne。当你在 Reflector 中看到编译好的 dll 时,TestTwo 变成了 TestOne。

我编译了以下代码并在 ILDASM 中打开它们。

    public bool TestOne(int l, int e, int u, int r)
    {
        return (l != e && l != u && l != r);
    }

    public bool TestTwo(int l, int e, int u, int r)
    {
        return (!(l == e || l == u || l == r));
    }

以下是我在 ILDASM 中看到的(基于发布版本)。

.method public hidebysig instance bool  TestOne(int32 l,
                                                int32 e,
                                                int32 u,
                                                int32 r) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  beq.s      IL_0011
  IL_0004:  ldarg.1
  IL_0005:  ldarg.3
  IL_0006:  beq.s      IL_0011
  IL_0008:  ldarg.1
  IL_0009:  ldarg.s    r
  IL_000b:  ceq
  IL_000d:  ldc.i4.0
  IL_000e:  ceq
  IL_0010:  ret
  IL_0011:  ldc.i4.0
  IL_0012:  ret
} // end of method Program::TestOne

.method public hidebysig instance bool  TestTwo(int32 l,
                                                int32 e,
                                                int32 u,
                                                int32 r) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  ldarg.1
  IL_0001:  ldarg.2
  IL_0002:  beq.s      IL_0011
  IL_0004:  ldarg.1
  IL_0005:  ldarg.3
  IL_0006:  beq.s      IL_0011
  IL_0008:  ldarg.1
  IL_0009:  ldarg.s    r
  IL_000b:  ceq
  IL_000d:  ldc.i4.0
  IL_000e:  ceq
  IL_0010:  ret
  IL_0011:  ldc.i4.0
  IL_0012:  ret
} // end of method Program::TestTwo

我使用 VS2008 sp1 (.NET 3.5 sp1) 来测试这段代码。

【讨论】:

    【解决方案3】:

    有句话叫“先行,后行!”。我假设两个版本之间的差异(如果存在的话)不会影响您的应用程序的整体性能——至少在所有应用程序的 99.99% 中是这样。如果您的应用程序是剩下的 0.001% 之一,那么您正在编写非常特殊和复杂的高速软件。在这种情况下,您不应该使用理论工具。在真实的生活条件下进行测量!

    【讨论】:

      【解决方案4】:

      我相信它取决于实现...
      据我所知,在基于 .Net 的平台上,当使用 && 运算符时,表达式从左到右求值,如果左操作数为假,正确的甚至没有被评估。按照这个逻辑,如果最左边的操作数之一被证明是错误的,我觉得选项 A 将是一个选择并且更快。我想这可能是 IL 生成更喜欢使用 TestOne 方法的原因(顺便说一下,推断选择的路径是什么的好主意,谢谢 Chansik Im。

      【讨论】:

        猜你喜欢
        • 2011-11-27
        • 1970-01-01
        • 2015-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-16
        • 2010-12-24
        相关资源
        最近更新 更多