Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re: Re: Re: Perl Idioms Explained: && and || "Short Circuit" operators

by BrowserUk (Pope)
on Oct 22, 2003 at 23:09 UTC ( #301418=note: print w/replies, xml ) Need Help??

in reply to Re: Re: Perl Idioms Explained: && and || "Short Circuit" operators
in thread Perl Idioms Explained - && and || "Short Circuit" operators

Now you've confused me:)

Doesn't O(1) (in this case) mean that a condition is only tested once with the C-switch statement. Whereas the implementation shown in the OP, all tests from 0 to N where N is the met condition's lexical position within the group, hence worst case O(N) if the last case is the one chosen?

It was this bit of your post that confused me

...Im wracking my brain to see how this could be done without becoming hopelessly inefficient....

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

  • Comment on Re: Re: Re: Perl Idioms Explained: && and || "Short Circuit" operators

Replies are listed 'Best First'.
Re: Re: Re: Re: Perl Idioms Explained: && and || "Short Circuit" operators
by demerphq (Chancellor) on Oct 22, 2003 at 23:30 UTC

    Well, what I mean is that I dont see how in C the conditional is only evaluated once. I dont know enough about how C implements a case statement to say for sure But i dont see how a case statement could be implemented in such a way without adding a lot of code to the statement, which would potentially be far more expensive than converting it to a series of conditionals. For instance something like this

    switch (val) { case 1 : handle_case1; break; case 2 : handle_case2; break; case 5 : handle_case5; case 10: handle_case10; default: handle_default; }

    I would guess would get converted to something like

    if (val == 1) { handle_case1; } elsif (val == 2) { handle_case2; } else { if (val == 5) { goto CASE5; } elsif (val == 10) { goto CASE10; } else { goto DEFAULT; } CASE5: handle_case5; CASE10: handle_case10; DEFAULT: handle_default; }

    Or something like it. I just dont see how it could be handled otherwise. Perhaps the fact that it only operates on ints means that there is a neater optimisation. But if you extend switch to handle strings as it does in pascal then I think the situation becomes even more difficult.

    Thanks to the CB for clarifying that switch only handles ints. That issue may make my ruminations on this invalid. I dont know. Id be interested to hear from someone that does. As I said, this issue confuses me. :-)


      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi

      No. On every implementation I've seen, switch/case is implemented almost exactly like perl's goto-EXPR, except that the target label is actually a machine instruction address known at compile time.

      This simple C program

      #include <stdio.h> int main() { switch ( 4 ) { case 1: printf( "case1\n" ); break; case 2: printf( "case2\n" ); break; case 3: printf( "case3\n" ); break; case 4: printf( "case4\n" ); break; case 5: printf( "case5\n" ); break; case 6: printf( "case6\n" ); break; } }

      Is translated into this assembler

      The salient part of which is

      ; switch ( 4 ) { ; @1: mov eax,4 // Load the selector expression (4) cmp eax,6 // Test if its outside the range of options (6) ja short @2 // If it is, jump to the default /* Otherwise, add the value * the size of the lookup table entries (4bytes) and add it to the base address of the dispatch table, then jump to the address help at that location in the table. */ jmp dword ptr [@10+4*eax] @10: dd @2 dd @9 dd @8 dd @7 dd @6 dd @5 dd @4 ; ; case 1: printf( "case1\n" ); break; ; @9:

      Originally, the offsets were byte offsets and the table size had a maximum of 255. These days, the table entries are absolute 32-bit addresses and the table size can theoretically be 2 GB in size. In all cases, it is very fast.

      The interesting part is coding the switch expression so that it converts your range of possible matches to an integer. String lookups can be index using str(i)(n)cmp() quite easily, but I've had to code some more esoteric versions in the past.

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

        So would I be correct in understanding that

        switch (ulong_val) { case 0 : handle_case0; break; case ULONGMAX: handle_caseMAX; break; default : handle_default; break; }

        Generates a _huge_ dispatch table? Can that be correct? I found your dissambly to be very interesting, but I personaly would have like to have seen what happens when the input is discontiguous and operated on a variable and not a constant. Any chance of an update BrowserUk?


          First they ignore you, then they laugh at you, then they fight you, then you win.
          -- Gandhi

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://301418]
[Corion]: haukex: Hmm - maybe I can reuse that. I see that it uses Pod::Parser, which I think was one of the more fragile parsers. But if I'm statically (re)generating the tests instead of doing that "live" on the client/tester machines, that's a much smaller...
[Corion]: ... problem space than trying to cater to all versions of Pod::Parser(s)
[haukex]: I think you're right, I think Pod::Simple is the preferred parser now
[haukex]: But I was just using it as an author test anyway
[Corion]: haukex: Aaah - I thought you were still running these tests on every machine, but you only run these as author or Devel::Cover tests
[Corion]: haukex: Yeah, I think back then I used Test::Inline, which used a pod parser that was going through some changes and I didn't want to cater for all the various versions and thus stopped testing the Pod completely
[choroba]: I usually do this with presentations
[Corion]: But now I think statically (re)generating the Pod tests is a saner approach, and likely I'll regenerate the tests either in Makefile.PL or from xt/ but have them live below t/
[choroba]: I keep the snippets in files of their own, and use a Makefile to syntax highlight them and insert them into slides, while also running them and inserting the output if required
[Corion]: choroba: Ooooh - I didn't think of that! I write my presentations as POD and if it "roughly" looks like Perl code, I should also syntax-check that...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (10)
As of 2017-02-27 12:22 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (385 votes). Check out past polls.