首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译器是否会针对布尔赋值进行优化?

编译器是否会针对布尔赋值进行优化?
EN

Stack Overflow用户
提问于 2012-06-01 23:01:44
回答 3查看 754关注 0票数 4

这就是我想要做的:

代码语言:javascript
复制
if(ABoolean || (BBoolean && CBoolean))
{
    SomeButton.Enabled = true;
    AnotherButton.Enabled = true;
}
else 
{
    SomeButton.Enabled = false;
    AnotherButton.Enabled = false;
}

我可以将其切换为:

代码语言:javascript
复制
SomeButton.Enabled = (ABoolean || (BBoolean && CBoolean));
AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean));

获取更简洁的代码。我的问题是,编译器是否对赋值进行了优化,使得它会看到布尔表达式是相同的,并为第二个按钮赋值,还是每次都计算这个值。

注意:我知道这是一个微不足道的例子,加速/减速将微不足道,但它将有助于我更好地理解编译器优化。

编辑:以下是我认为第二个选项可能会优化的原因:

代码语言:javascript
复制
class Program
{
    static bool ABoolean = true, BBoolean = true, CBoolean = false;
    static bool AEnable, BEnable;


    static void Main(string[] args)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000000000; i++)
        {
            Operation1();
        }
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);

        Stopwatch sw1 = new Stopwatch();
        sw1.Start();
        for (int i = 0; i < 1000000000; i++)
        {
            Operation2();
        }
        sw1.Stop();
        Console.WriteLine(sw1.ElapsedMilliseconds);
        Console.Read();
    }

    static void Operation1()
    {
        if (ABoolean || (BBoolean && CBoolean))
        {
            AEnable = true;
            BEnable = true;
        }
        else
        {
            AEnable = false;
            BEnable = false;
        }
    }

    static void Operation2()
    {
        AEnable = (ABoolean || (BBoolean && CBoolean));
        BEnable = (ABoolean || (BBoolean && CBoolean));
    }
}

这导致了大约8-9秒的差异,超过了10亿次操作(第二个选项运行得更快)。然而,随着我添加了更多的"Enable“布尔值,第二个操作变得更慢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-01 23:04:58

不,我不期望编译器对此进行优化。JIT可能会对此进行优化(因为它有更多信息),但我不希望C#编译器这样做。

编译器如何知道SomeButton.Enabled是否会产生一些副作用,从而改变ABooleanBBooleanCBoolean的值

编辑:验证此...让我们给C#编译器绝对最大的机会:

代码语言:javascript
复制
class Test
{
    static void Main()
    {
        Foo(true, false, true);
    }

    static void Foo(bool x, bool y, bool z)
    {
        A = x || (y && z);
        B = x || (y && z);
    }

    static bool A { get; set; }
    static bool B { get; set; }
}

使用以下命令编译:

代码语言:javascript
复制
csc /o+ /debug- Test.cs

通过ILDASM实现Foo的代码:

代码语言:javascript
复制
.method private hidebysig static void  Foo(bool x,
                                           bool y,
                                           bool z) cil managed
{
  // Code size       37 (0x25)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000c
  IL_0003:  ldarg.1
  IL_0004:  brfalse.s  IL_0009
  IL_0006:  ldarg.2
  IL_0007:  br.s       IL_000d
  IL_0009:  ldc.i4.0
  IL_000a:  br.s       IL_000d
  IL_000c:  ldc.i4.1
  IL_000d:  call       void Test::set_A(bool)
  IL_0012:  ldarg.0
  IL_0013:  brtrue.s   IL_001e
  IL_0015:  ldarg.1
  IL_0016:  brfalse.s  IL_001b
  IL_0018:  ldarg.2
  IL_0019:  br.s       IL_001f
  IL_001b:  ldc.i4.0
  IL_001c:  br.s       IL_001f
  IL_001e:  ldc.i4.1
  IL_001f:  call       void Test::set_B(bool)
  IL_0024:  ret
} // end of method Test::Foo

正如您所看到的,表达式在这两种情况下都会被计算。

票数 7
EN

Stack Overflow用户

发布于 2012-06-01 23:04:31

我的问题是,编译器是否对赋值进行了优化,使得它会看到布尔表达式是相同的,并为第二个按钮赋值,还是每次都计算这个值。

它将计算每次的值。

如果这是一个多线程的应用程序呢?其他线程可能会更改它。

如果它们不是常量变量,则可以更改。

优化你可以做的事情

代码语言:javascript
复制
SomeButton.Enabled = AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean));

在这种情况下,它将被计算一次,并首先将值分配给AnotherButton,然后再将值分配给SomeButton。记住它在赋值时从右到左。

票数 4
EN

Stack Overflow用户

发布于 2012-06-01 23:11:27

不,根据我的经验,编译器不会对其进行优化,但是,您可以这样做:

代码语言:javascript
复制
SomeButton.Enabled = AnotherButton.Enabled = (ABoolean || (BBoolean && CBoolean));
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10852722

复制
相关文章

相似问题

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