什么是发生在一个"如果(.. || ..)"和"如果(...&安培;&安培; ...)QUOT;内部构造? [英] What is happening in an "If(..||..)" and "If(...&&...)" construct internally?

查看:121
本文介绍了什么是发生在一个"如果(.. || ..)"和"如果(...&安培;&安培; ...)QUOT;内部构造?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道里面发生了什么是如果OR 如果和。我有一种感觉,它只是语法糖使用&放大器;&安培; || 和国内所有案件建立单if语句。

I was just wondering what happens inside of an "if OR" and "if AND". I have a feeling that it's just syntactic sugar to use && and || and internally all cases are build as single if statements.

紧凑型形式||:

if(a || b || c)
{
    DoSomething();
}



潜在的内部形式:

Potential internal form:

if(a)
{
    DoSomething();
}    
else if(b)
{
    DoSomething();
}    
else if(c)
{
    DoSomething();
}






紧凑的外形和放大器;


Compact form &&:

if(a && b && c)
{
    DoSomething();
}



潜在的内部形式:

Potential internal form:

if(a)
{
    if(b)
    {
        if(c)
        {
            DoSomething();
        }
    }
}



有没有在任何区别?这两个例子的表现。

Is there any difference in the performance of these two examples?

*编辑:添加了其他的||案例

* Added the else to the || case

推荐答案

首先, || &放大器;&安培; 短路。这意味着,在:

First of all, || and && are short-circuit. Which mean that in:

if(a || b || c)
    DoSomething();

如果 A 为真, b C 将不被计算。

if a is true, b and c will not be evaluated.

其次,你的实现的 || 是假的:

Secondly, your implementation of the || is false:

if(a)
    DoSomething();
if(b)
    DoSomething();
if(c)
    DoSomething();



DoSomething的()将被召入3次

应该是:

if(a)
    DoSomething();
else if(b)
    DoSomething();
else if(c)
    DoSomething();

要完成,如果你想的性能的第一个喜欢短的呼叫你的条件

To finish, if you want performance prefer shorter call first in your conditions:

if(aShortFunctionToExecute() || aVeryVeryLongFunctionToExecute())
     DoSomething();



将比

Will be faster than

if(aVeryVeryLongFunctionToExecute() || aShortFunctionToExecute())
     DoSomething();

由于的懒评价

如果你的反汇编代码:

private static void Main()
{
    if (a() && b() && c())
    {
        Console.WriteLine("DoSomething");
    }
}
bool a(){
    return true;
}
bool b(){
    return 3 % 2 == 1;
}
bool c(){
    return (3 % 2) / 1 == 1;
}

您会得到:

    if (a() && b() && c())
00000022  call        FFFFFFFFFFEE8D90 
00000027  mov         byte ptr [rbp+20h],al 
0000002a  movzx       eax,byte ptr [rbp+20h] 
0000002e  test        eax,eax 
00000030  je          000000000000005A 
00000032  call        FFFFFFFFFFEE8D98 
00000037  mov         byte ptr [rbp+21h],al 
0000003a  movzx       eax,byte ptr [rbp+21h] 
0000003e  test        eax,eax 
00000040  je          000000000000005A 
00000042  call        FFFFFFFFFFEE8DA0 
00000047  mov         byte ptr [rbp+22h],al 
0000004a  movzx       ecx,byte ptr [rbp+22h] 
0000004e  xor         eax,eax 
00000050  test        ecx,ecx 
00000052  sete        al 
00000055  mov         dword ptr [rbp+24h],eax 
00000058  jmp         0000000000000062 
0000005a  nop 
0000005b  mov         dword ptr [rbp+24h],1 
00000062  nop 
00000063  movzx       eax,byte ptr [rbp+24h] 
00000067  mov         byte ptr [rbp+2Fh],al 
0000006a  movzx       eax,byte ptr [rbp+2Fh] 
0000006e  test        eax,eax 
00000070  jne         0000000000000087 
        {
00000072  nop 
            Console.WriteLine("DoSomething");
00000073  mov         rcx,12603398h 
0000007d  mov         rcx,qword ptr [rcx] 
00000080  call        00000000577A82A0 
00000085  nop 
        }

和的代码:

private static void Main()
{
    if (a())
        if(b())
            if(c())
                Console.WriteLine("DoSomething");
}
static bool a(){
    return true;
}
static bool b(){
    return 3 % 2 == 1;
}
static bool c(){
    return (3 % 2) / 1 == 1;
}

您会得到:

if (a())
00000022  call        FFFFFFFFFFEE8D90 
00000027  mov         byte ptr [rbp+20h],al 
0000002a  movzx       ecx,byte ptr [rbp+20h] 
0000002e  xor         eax,eax 
00000030  test        ecx,ecx 
00000032  sete        al 
00000035  mov         dword ptr [rbp+24h],eax 
00000038  movzx       eax,byte ptr [rbp+24h] 
0000003c  mov         byte ptr [rbp+3Fh],al 
0000003f  movzx       eax,byte ptr [rbp+3Fh] 
00000043  test        eax,eax 
00000045  jne         00000000000000A4 
            if(b())
00000047  call        FFFFFFFFFFEE8D98 
0000004c  mov         byte ptr [rbp+28h],al 
0000004f  movzx       ecx,byte ptr [rbp+28h] 
00000053  xor         eax,eax 
00000055  test        ecx,ecx 
00000057  sete        al 
0000005a  mov         dword ptr [rbp+2Ch],eax 
0000005d  movzx       eax,byte ptr [rbp+2Ch] 
00000061  mov         byte ptr [rbp+3Fh],al 
00000064  movzx       eax,byte ptr [rbp+3Fh] 
00000068  test        eax,eax 
0000006a  jne         00000000000000A4 
                if(c())
0000006c  call        FFFFFFFFFFEE8DA0 
00000071  mov         byte ptr [rbp+30h],al 
00000074  movzx       ecx,byte ptr [rbp+30h] 
00000078  xor         eax,eax 
0000007a  test        ecx,ecx 
0000007c  sete        al 
0000007f  mov         dword ptr [rbp+34h],eax 
00000082  movzx       eax,byte ptr [rbp+34h] 
00000086  mov         byte ptr [rbp+3Fh],al 
00000089  movzx       eax,byte ptr [rbp+3Fh] 
0000008d  test        eax,eax 
0000008f  jne         00000000000000A4 
                    Console.WriteLine("DoSomething");
00000091  mov         rcx,125D3398h 
0000009b  mov         rcx,qword ptr [rcx] 
0000009e  call        00000000577B82A0 
000000a3  nop 

这是一个有点长。它需要40的指令,而不是31

Which is a bit longer: it takes 40 instructions instead of 31.

随着指出 thanosqr ,性能还取决于概率为您的病情是真实的。举他的例子:

As pointed out thanosqr, the performance also depend of the probability for your condition to be true. To take his example:

如果 A 失败的99%的时间,并采取1秒运行,如果 b
成功的99%的时间,并采取10秒跑,超过100次尝试,你会更快把 b 第一:

If a fails 99% of the time and take 1 sec to run and if b succeed 99% of the time and take 10 sec to run, over 100 tries you'll be faster putting b first:

if(b || a) => 10s 99% ==> 100 runs will take 99*10+11 = 1001s
if(b || a) => 11s 1%

if(a || b) => 11s 99% ==> 100 runs will take 99*11+1 = 1090s
if(a || b) => 1s 1%



另外,我建议你阅读这的为什么处理排序后的数组比排序的数组更快? 这是很有趣的!

这篇关于什么是发生在一个"如果(.. || ..)"和"如果(...&安培;&安培; ...)QUOT;内部构造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆