The answer lies in the assembly code generated by gcc ( -g and -O2 ). Two functions take value as an argument, which is first requested by the user (to force gcc not to delete unused code fragments, as well as the exception of dead code). Of course, the printf part is the same for both functions and gcc is optimized (for both), so it returns immediately after printing. Thus, a significant part is the beginning of both functions. Let them take a look:
0x080484d0 <+0>: push %ebp # - 0x080484d1 <+1>: mov %esp,%ebp # |- standard prologue 0x080484d3 <+3>: sub $0x28,%esp # - 0x080484d6 <+6>: mov 0x8(%ebp),%eax # get argument 0x080484d9 <+9>: movl $0x80484f8,-0x14(%ebp) # set up labels array 0x080484e0 <+16>: movl $0x8048510,-0x10(%ebp) 0x080484e7 <+23>: movl $0x8048528,-0xc(%ebp) 0x080484ee <+30>: jmp *-0x14(%ebp,%eax,4) # jump to appropriate sect. 0x080484f2 <+34>: lea 0x0(%esi),%esi
0x08048470 <+0>: push %ebp # - 0x08048471 <+1>: mov %esp,%ebp # |- standard prologue 0x08048473 <+3>: sub $0x18,%esp # - 0x08048476 <+6>: mov 0x8(%ebp),%eax # get argument 0x08048479 <+9>: cmp $0x1,%eax 0x0804847c <+12>: je 0x80484b8 <switchFunc+72> # jump here if value == 1 0x0804847e <+14>: cmp $0x2,%eax 0x08048481 <+17>: je 0x80484a0 <switchFunc+48> # if value == 2 0x08048483 <+19>: test %eax,%eax 0x08048485 <+21>: jne 0x804849b <switchFunc+43> # if value != 0 return
Both fragments have a “slow part”: the first spends most of the time creating an array of labels, while the second slowly decides which path to choose. So basically, their runtime is almost the same.
Which one is better? The second, one with a switch construct. It is standard C, more readable, convenient, and understandable.
source share