Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Modern C compilers have the smarts built in to make intelligent decisions on what code to emit. In the case of your example of 2 widely spaced cases, it produces this

?live1@0: ; ; int main( int argc, char * argv[] ) { ; push ebp mov ebp,esp push ecx ; ; unsigned long selector; ; sscanf( argv[1], "%li", &selector ); ; @1: lea eax,dword ptr [ebp-4] push eax push offset s@ mov edx,dword ptr [ebp+12] push dword ptr [edx+4] call _sscanf add esp,12 ; ; ; switch ( selector ) { ; mov ecx,dword ptr [ebp-4] sub ecx,-2147483648 je short @5 sub ecx,-2147483647 jne short @2 ; ; case 1 : printf( "case 1\n" ); +break; ; push offset s@+4 call _printf pop ecx @8: pop ecx pop ebp ret ; ; case 2147483648 : printf( "case 2147483648\n" ); + break; ; @5: push offset s@+12 call _printf pop ecx @9: pop ecx pop ebp ret ; ; default : printf( "default\n" ); + break; ; @2: push offset s@+29 call _printf pop ecx ; ; } ; } ; @6: @7: pop ecx pop ebp ret _main endp _TEXT ends

Which as you can see, gets translated into a test and jump for the extreme case, another test and jump for the default case and a fall through for the 1 case.

If you combine a contiguous range and an extreme case, you get.

_TEXT segment dword public use32 'CODE' _main proc near ?live1@0: ; ; int main( int argc, char * argv[] ) { ; push ebp mov ebp,esp push ecx ; ; unsigned long selector; ; sscanf( argv[1], "%li", &selector ); ; @1: lea eax,dword ptr [ebp-4] push eax push offset s@ mov edx,dword ptr [ebp+12] push dword ptr [edx+4] call _sscanf add esp,12 ; ; ; switch ( selector ) { ; mov ecx,dword ptr [ebp-4] cmp ecx,3 jg short @11 je short @7 sub ecx,-2147483648 je short @10 sub ecx,-2147483647 je short @9 dec ecx je short @8 jmp short @2 @11: sub ecx,4 je short @6 dec ecx je short @5 dec ecx je short @4 jmp short @2 ; ; case 1 : printf( "case 1\n" ); +break; ; @9: push offset s@+4 call _printf pop ecx @14: pop ecx pop ebp ret ; ; case 2 : printf( "case 2\n" ); + break; ; @8: push offset s@+12 call _printf pop ecx @15: pop ecx pop ebp ret ; ; case 3 : printf( "case 3\n" ); + break; ; @7: push offset s@+20 call _printf pop ecx @16: pop ecx pop ebp ret ; ; case 4 : printf( "case 4\n" ); + break; ; @6: push offset s@+28 call _printf pop ecx @17: pop ecx pop ebp ret ; ; case 5 : printf( "case 5\n" ); + break; ; @5: push offset s@+36 call _printf pop ecx @18: pop ecx pop ebp ret ; ; case 6 : printf( "case 6\n" ); + break; ; @4: push offset s@+44 call _printf pop ecx @19: pop ecx pop ebp ret ; ; case 2147483648 : printf( "case 2147483648\n" ); + break; ; @10: push offset s@+52 call _printf pop ecx @20: pop ecx pop ebp ret ; ; default : printf( "default\n" ); + break; ; @2: push offset s@+69 call _printf pop ecx ; ; } ; } ; @12: @13: pop ecx pop ebp ret _main endp _TEXT ends

Which has been converted into a test cascade something like the original Perl code. However, this is before the optimiser has gone to work on it. Once the optimiser sees that code, it is quite likely that it will revert to using a dispatch table for the continuous cases with a single test for the extreme case. I having having trouble obtaining a post - optimisation disassembly that is readable. I'll try to update with that later.

As you might guess, if your range of cases is a widely spread set of discontiguous cases, then the result is you end up with cascaded tests just like the perl version. However, in almost every case (sic:) I remember using, I found some fairly simple function theat mapped the range to a contiguous or near-contiguous integer range. When this isn't the case, then I use an if/else cascade instead.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
Hooray!


In reply to Re+ :Perl Idioms Explained: && and || "Short Circuit" operators by BrowserUk
in thread Perl Idioms Explained - && and || "Short Circuit" operators by davido

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-20 05:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found