0

Suppose I have a variable that depends on a condition. From the efficiency perspective, should I use

int s;
if (d > 2)
{
   s = -1;
}
else
{
   s = 1;
}

or just

int s = 1;
if (d > 2)
{
   s = -1;
}

Can someone explain the difference? Is there any difference between a compiled language (e.g. C) vs an interpreted one (e.g. Python)?

Notice that this question is related with a previous question of mine, and the reason I'm asking is the same: it is very frequent in any programming language, and I always end up asking myself what should I use.

Community
  • 1
  • 1
Jorge Leitao
  • 19,085
  • 19
  • 85
  • 121
  • 6
    It completely depends on the compiler/interpreter. It's more important to use the one that makes the most sense when you're reading the code. If your program is too slow because of this type of syntactical decision, don't worry about the syntax, worry about the design. – xaxxon Jun 19 '13 at 07:54
  • 1
    try to generate the assembly code and see the difference. you can generate the assembly code from C code with `gcc -S` – MOHAMED Jun 19 '13 at 07:54
  • Odd that you need to ask it again despite various responses that pretty much answer what you're asking now. – devnull Jun 19 '13 at 08:05
  • possible duplicate of [If-Else-Return or just if-Return?](http://stackoverflow.com/questions/9191388/if-else-return-or-just-if-return) – devnull Jun 19 '13 at 08:05
  • @devnull, I'm sorry, for me was not clear that the answers in that question also answer this one. Nevetheless, I'm probability not so experienced as you in programming, so feel free to close this one if you don't agree with it. – Jorge Leitao Jun 19 '13 at 08:08

7 Answers7

1

No difference, with optimization gcc -S -O2 you give the same output:

    .file   "demo.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB11:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $-1, %esi
    movl    $.LC0, %edi
    xorl    %eax, %eax
    call    printf
    xorl    %eax, %eax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE11:
    .size   main, .-main
    .ident  "GCC: (Debian 4.7.2-5) 4.7.2"
    .section    .note.GNU-stack,"",@progbits
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
1

If you really have tons of code like this where you are initializing to 1 or -1, and it really gets run tons of times so it can affect performance, you can use a branchless version instead:

int s = 1 - 2*(d > 2);

More generally, you could set up an array for initialization values:

const int s_ini[2] = { 1, -1 };
int s = s_ini[d > 2];
jxh
  • 69,070
  • 8
  • 110
  • 193
1

This is a case where I personally would prefer the (sometimes dreaded) ternary operator ?:, like so:

const int s = (d < 2) ? -1 : 1;

Since:

  1. This allows s to be const, which in my opinion is a huge win. Of course this assumes the variable is only read after being initialized.
  2. It (like other solutions) only writes to s once, which can be faster.

I avoided "clever tricks" with with the computation.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

From my point of view, this is not a question of performance. Most compiler will produce the same code, and if they don't, that shouldn't have any noticeable performance impact. Unless you are working on very very (very) tight environment where each CPU cycle count. Which shouldn't be the case, unless you are a time traveler just arriving from the seventies'...

More seriously, as it was noticed several times in the various comments, this is more a matter of readability and communication. After that, it is hard to say that one form is better than the other.

My personal habit is to use if ... else ... when I want to put emphasis on the fact there is clearly two different path of equal "weight" in the program. I use the alternative set to default; if ... when I want to say "Well, that if is a special case".

Since this is related to an other of your questions, you might consider the form without else as some kind of guard clause, like a if ... return ...; return ...

Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
0

The performance difference isn't really important, but your first notation is most clear for others programmers.

int s;
if (d > 2)
   s = -1;
else
   s = 1;

When a programmer will se "int s = 1;" he will probably don't understand why you initialize this variable at 1, for put it a -1 two lignes after.

Shar
  • 455
  • 2
  • 14
0

There is no right and wrong in such cases. It depends. I believe that even if there might be a slight difference in run time, you should almost always prefer code maintainability.

In this case a default is better as you must pass all the conditions to return successfully.

    int rc = FAIL;

    /* do something */

    if (some-cond)
        goto end;

    /* do something */

    if (some-cond)
        goto end;

    rc = SUCCESS;

end:
    /* clean-up */
    return rc;
eyalm
  • 3,366
  • 19
  • 21
0

From the readability of code, I think the former one is better. If you want to get better performance, I think you can do as @jxh answers.

Charles0429
  • 1,406
  • 5
  • 15
  • 31