Which is faster : if (bool) or if(int)?

后端 未结 8 2106
离开以前
离开以前 2020-12-07 14:48

Which value is better to use? Boolean true or Integer 1?

The above topic made me do some experiments with bool and in

8条回答
  •  温柔的废话
    2020-12-07 14:58

    When I compile this with a sane set of options (specifically -O3), here's what I get:

    For f():

            .type   _Z1fi, @function
    _Z1fi:
    .LFB0:
            .cfi_startproc
            .cfi_personality 0x3,__gxx_personality_v0
            cmpl    $1, %edi
            sbbl    %eax, %eax
            andb    $58, %al
            addl    $99, %eax
            ret
            .cfi_endproc
    

    For g():

            .type   _Z1gb, @function
    _Z1gb:
    .LFB1:
            .cfi_startproc
            .cfi_personality 0x3,__gxx_personality_v0
            cmpb    $1, %dil
            sbbl    %eax, %eax
            andb    $58, %al
            addl    $99, %eax
            ret
            .cfi_endproc
    

    They still use different instructions for the comparison (cmpb for boolean vs. cmpl for int), but otherwise the bodies are identical. A quick look at the Intel manuals tells me: ... not much of anything. There's no such thing as cmpb or cmpl in the Intel manuals. They're all cmp and I can't find the timing tables at the moment. I'm guessing, however, that there's no clock difference between comparing a byte immediate vs. comparing a long immediate, so for all practical purposes the code is identical.


    edited to add the following based on your addition

    The reason the code is different in the unoptimized case is that it is unoptimized. (Yes, it's circular, I know.) When the compiler walks the AST and generates code directly, it doesn't "know" anything except what's at the immediate point of the AST it's in. At that point it lacks all contextual information needed to know that at this specific point it can treat the declared type bool as an int. A boolean is obviously by default treated as a byte and when manipulating bytes in the Intel world you have to do things like sign-extend to bring it to certain widths to put it on the stack, etc. (You can't push a byte.)

    When the optimizer views the AST and does its magic, however, it looks at surrounding context and "knows" when it can replace code with something more efficient without changing semantics. So it "knows" it can use an integer in the parameter and thereby lose the unnecessary conversions and widening.

提交回复
热议问题