Thread: if is faster than switch?

  1. #16
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Here is the whole output file (sorry for taking up so much space ^^). I noticed some kind of huge lookup table at the bottom (L287). That may make the switch fast, but quite large.
    Code:
    	TITLE	E:\Programming\Cpp\Test\SwitchIfTest.cpp
    	.386P
    include listing.inc
    if @Version gt 510
    .model FLAT
    else
    _TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT	ENDS
    _DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
    _DATA	ENDS
    CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
    CONST	ENDS
    _BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
    _BSS	ENDS
    $$SYMBOLS	SEGMENT BYTE USE32 'DEBSYM'
    $$SYMBOLS	ENDS
    $$TYPES	SEGMENT BYTE USE32 'DEBTYP'
    $$TYPES	ENDS
    _TLS	SEGMENT DWORD USE32 PUBLIC 'TLS'
    _TLS	ENDS
    ;	COMDAT _main
    _TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT	ENDS
    FLAT	GROUP _DATA, CONST, _BSS
    	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
    endif
    PUBLIC	_main
    ;	COMDAT _main
    _TEXT	SEGMENT
    _Alpha$ = -4
    _main	PROC NEAR					; COMDAT
    ; File E:\Programming\Cpp\Test\SwitchIfTest.cpp
    ; Line 2
    	push	ebp
    	mov	ebp, esp
    	sub	esp, 72					; 00000048H
    	push	ebx
    	push	esi
    	push	edi
    	lea	edi, DWORD PTR [ebp-72]
    	mov	ecx, 18					; 00000012H
    	mov	eax, -858993460				; ccccccccH
    	rep stosd
    ; Line 3
    	mov	DWORD PTR _Alpha$[ebp], 0
    
    ; Line 6
    	cmp	DWORD PTR _Alpha$[ebp], 1
    	jne	SHORT $L268
    ; Line 8
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 10
    	jmp	SHORT $L274
    $L268:
    	cmp	DWORD PTR _Alpha$[ebp], 10		; 0000000aH
    	jne	SHORT $L270
    ; Line 12
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 14
    	jmp	SHORT $L274
    $L270:
    	cmp	DWORD PTR _Alpha$[ebp], 56		; 00000038H
    	jne	SHORT $L272
    ; Line 16
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 18
    	jmp	SHORT $L274
    $L272:
    	cmp	DWORD PTR _Alpha$[ebp], 128		; 00000080H
    	jne	SHORT $L274
    ; Line 20
    	mov	DWORD PTR _Alpha$[ebp], 0
    $L274:
    
    ; Line 25
    	mov	eax, DWORD PTR _Alpha$[ebp]
    	mov	DWORD PTR -8+[ebp], eax
    	mov	ecx, DWORD PTR -8+[ebp]
    	sub	ecx, 1
    	mov	DWORD PTR -8+[ebp], ecx
    	cmp	DWORD PTR -8+[ebp], 127			; 0000007fH
    	ja	SHORT $L276
    	mov	eax, DWORD PTR -8+[ebp]
    	xor	edx, edx
    	mov	dl, BYTE PTR $L287[eax]
    	jmp	DWORD PTR $L288[edx*4]
    $L279:
    ; Line 27
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 28
    	jmp	SHORT $L276
    $L280:
    ; Line 31
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 32
    	jmp	SHORT $L276
    $L281:
    ; Line 35
    	mov	DWORD PTR _Alpha$[ebp], 0
    ; Line 36
    	jmp	SHORT $L276
    $L282:
    ; Line 39
    	mov	DWORD PTR _Alpha$[ebp], 0
    $L276:
    
    ; Line 43
    	xor	eax, eax
    ; Line 44
    	pop	edi
    	pop	esi
    	pop	ebx
    	mov	esp, ebp
    	pop	ebp
    	ret	0
    $L288:
    	DD	$L279
    	DD	$L280
    	DD	$L281
    	DD	$L282
    	DD	$L276
    $L287:
    	DB	0
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	1
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	2
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	4
    	DB	3
    _main	ENDP
    _TEXT	ENDS
    END
    Last edited by Magos; 02-29-2004 at 05:46 PM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #17
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Well, you can take the words "reasonably contiguous" out of my original description. It seems excessive to generate a 128 byte lookup table for a 4 case switch. I wonder what the upper limit for this is.
    Code:
    switch (x)
    {
    	case 0:
    	    ...
    	case 64000:
    	    ...
    }
    Surely this doesn't generate a 64KB lookup table?
    Code:
    	mov	dl, BYTE PTR $L287[eax]
    	jmp	DWORD PTR $L288[edx*4]
    If anyone is stumped, like I was, on how dl == edx, apparently dl is the lower 8 bits of the 32bit register edx.

    Code:
    [--------|--------|--------|--------]
     ________________edx________________
                       _______dx________
                                ___dl___

  3. #18
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Originally posted by skorman00
    I always wanted to learn assembly, and with Magos' post, I see this as a perfect time to start

    would you be able to point me to a decent assembler/tutorial?
    Flashdaddee has an ASM forum...
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #19
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    Originally posted by skorman00
    no, he doesn't even remember where he read it. He only saw it as an interesting tid bit, he never worries about it himself.
    Well, I have a book that says switch "will usually be faster than anything but the most basic if-else statement"
    Gambling. The new yoga, with cash prizes!

  5. #20
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Omnius, the question has already been thoroughly explored, down to the very assembly-level representation of it. Well, "an assembly-level representation" would be more accurate, but that doesn't matter. For more information, read Prelude's post.

    Summary:
    a) It doesn't really matter. Use whatever you like.

    b) If you DO care which is faster for some absurd reason:
    ->Case I - there IS a difference:
    It still doesn't matter unless you know assembly, since you won't be able to figure it out otherwise.
    ->Case II - there ISN'T a difference:
    It really, truly, absolutely, exhaustively doesn't matter, because there's no difference.

    c) If you DON'T care, please refer to (a).

    Conclusion:
    It doesn't really matter.

    ~~The End~~

    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #21
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    http://developer.intel.com/design/pentium4/manuals/

    The intel developer documentation gives you all the information on how intel processors work and how the instruction sets are create from binary numbers. Very informative if you want to read up on assembly.


    http://webster.cs.ucr.edu/

    The Art of Assembly- Free online book and assembler that you can use to learn assembly if you are interested.

    I read alot now if I can just program alot.

  7. #22
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    Originally posted by Hunter2
    Omnius, the question has already been thoroughly explored, down to the very assembly-level representation of it. Well, "an assembly-level representation" would be more accurate, but that doesn't matter. For more information, read Prelude's post.

    Summary:
    a) It doesn't really matter. Use whatever you like.

    b) If you DO care which is faster for some absurd reason:
    ->Case I - there IS a difference:
    It still doesn't matter unless you know assembly, since you won't be able to figure it out otherwise.
    ->Case II - there ISN'T a difference:
    It really, truly, absolutely, exhaustively doesn't matter, because there's no difference.

    c) If you DON'T care, please refer to (a).

    Conclusion:
    It doesn't really matter.

    ~~The End~~

    Thanks Hunter2. Some of us may still have an interest in the points discussed in the thread and don't consider it absurd to do so.

    Cheers,
    Omni.
    Gambling. The new yoga, with cash prizes!

  8. #23
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Originally posted by Omnius
    Well, I have a book that says switch "will usually be faster than anything but the most basic if-else statement"
    I believe your book is correct, because from reading this thread, it appears most compilers will generate a jump table for most switch statements (unless the cases have large values). So unless you only have a couple of else's, the switch should be faster.

    And thanks for the links Manofsteel.

  9. #24
    Registered User
    Join Date
    Feb 2002
    Posts
    465
    too many people worry about optimizing stupid things like "if/else vs switch".

    if your program is running slow, i seriously doubt its because you are using a switch statement instead of an if...
    I came up with a cool phrase to put down here, but i forgot it...

  10. #25
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    We know. Bludstayne and Prelude have already mentioned it. And hence the point of my summary: It doesn't really matter.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  11. #26
    Registered User
    Join Date
    Sep 2003
    Posts
    135
    Originally posted by ...
    too many people worry about optimizing stupid things like "if/else vs switch".

    if your program is running slow, i seriously doubt its because you are using a switch statement instead of an if...
    I'd say that in the vast majority of cases I'd have to agree with you. However, there are people working with programmes where even such small gains can be important. In those cases, then, such an optimisation would not be 'stupid' but would be essential. Presumably by this stage more significant gains will already have been made through choice of algorithm, etc etc.

    I doubt that a generalisation about which is faster will help matters in such cases, and the only way to know for sure if there's a gain to be had would be to measure.
    Gambling. The new yoga, with cash prizes!

  12. #27
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    In both cases they both require a comparison and they both jump based on the flags result of that comparison. I can't fathom how or why one would be faster than the other even in assembly code. Since both are jumping short they will both be extremely fast and this is not going to bog down your code unless you get pretty crazy with either of em.

    If you want to optimize your code stop spending 80% of your time on the 20% of your code that doesn't need it. The profiler will show you exactly where your code bogs. My guess is it would be in loops, mathematics, structure, data storage/retrieval, rendering, etc., not based on whether or not you used an if or a switch.

    The entire discussion is a mute point.

  13. #28
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    In both cases they both require a comparison and they both jump based on the flags result of that comparison. I can't fathom how or why one would be faster than the other even in assembly code. Since both are jumping short they will both be extremely fast and this is not going to bog down your code unless you get pretty crazy with either of em.
    Bubba, there is a difference. I don't think you thought it through completely.

  14. #29
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Nope. They can be coded the same. Just because the compiler chooses to create some lookup table for address translation or retrieval does not mean it has to be coded that way. Both require a comparison followed by a j(x) opcode. Both are going to jump around and both are only going to jump around one time - provided that break is used at the end of the case in C. If not, then all cases will be executed which would result in several more jumps.



    if (value==0)
    {
    DoSomething();
    }
    else
    {
    value=1;
    }

    Code:
    ....
    mov          eax,value
    cmp          eax,0
    jne           SetValue
    call           DoSomething
    jmp          Done
    SetValue:
    mov         eax,1   ;1 would not look like this...but you get it
    mov         value,eax
    
    Done:
    ...
    Now that's not how the disassembly will look exactly, it will probably use a different method but the general idea is the same.


    Besides all the compiler is doing for a switch or nested if's is creating an array which holds the correct values to place into the variable - hence _alpha$[ebp]. I suppose it would do the same with function addresses.

    Both look to be using a linear array to do what the programmer wants. So, in theory, neither would be faster. And again this is a mute point because using ifs or switches is not going to gain you that many cycles in your code.

    Compiler writers probably figured out that using a linear array to hold all possible values was quicker. I dunno because I didn't write the compiler.
    Last edited by VirtualAce; 03-05-2004 at 06:59 PM.

  15. #30
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Originally posted by Omnius
    Well, I have a book that says switch "will usually be faster than anything but the most basic if-else statement"
    Bubba, you're an extremely smart programmer. And you know a lot more about this stuff than I do. But I think you missed the above quote.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. ascii rpg help
    By aaron11193 in forum C Programming
    Replies: 18
    Last Post: 10-29-2006, 01:45 AM
  3. Switch
    By cogeek in forum C Programming
    Replies: 4
    Last Post: 12-23-2004, 06:40 PM
  4. Switch Case
    By FromHolland in forum C++ Programming
    Replies: 7
    Last Post: 06-13-2003, 03:51 AM