Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^6: Who's a thief? (No memory growth with magic goto)

by demerphq (Chancellor)
on Jan 14, 2005 at 19:55 UTC ( #422368=note: print w/replies, xml ) Need Help??


in reply to Re^5: Who's a thief? (No memory growth with magic goto)
in thread Who's a thief? -- the follow up

You can avoid magic stuff with a more cumbersome notation:

sub deep {SUB:{ ++$count and --$_[ 0 ] and redo SUB; }}

Which is actually going to be faster afaik. (Havent tested though)

---
demerphq

Replies are listed 'Best First'.
Re^7: Who's a thief? (No memory growth with magic goto)
by BrowserUk (Pope) on Jan 14, 2005 at 20:58 UTC

    Yes, that does appear to be (crudely measured) about twice as fast, though it wouldn't work for mutally recursive subs.

    #!/usr/bin/perl -w use strict; $|++; my $count; deep( $ARGV[ 0 ] ); print $count; sub deep {SUB:{ ++$count and --$_[ 0 ] and redo SUB; }} #sub deep { # ++$count and --$_[ 0 ] and goto \&deep; #} __DATA__ [20:54:56.63] P:\test>422344 10000000 10000000 [20:54:59.48] P:\test>422344 [20:55:17.40] P:\test>422344 100000000 100000000 [20:55:41.24] P:\test>

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.

      Well, thats true I suppose but im not sure its entirely relevent, the tail recursion optimization only applies to subs which call themselves as the last statement. So insofar as the mutually recursive routines are tail recursive as well this optimization pattern still applies.

      For those that dont know, (not you BrowserUK) tail optimization is really only _important_ in languages without looping constructs, in any language with looping constructs its just a nice bonus.

      ---
      demerphq

        I simply meant that I don't see any easy way of avoiding the goto in these mutually recursive routines:

        #! perl -slw use strict; my( $count1, $count2 ); sub a1 { b1( $_ [ 1 ] ); goto &a2; } sub a2 { $count1++; $_[ 0 ]-- and goto &b2; } sub b1 { $_[ 0 ]-- and goto &b2; } sub b2 { $count2++; goto &a2; } my( $n1, $n2 ) = ( 100, 50 ); a1( $n1, $n2 ); print "c1: $count1; c2: $count2"; __END__ [15:37:55.16] P:\test>mutrec c1: 151; c2: 150

        This is not a particularly useful example, but imagine that one (pair) are reading a huge XML file for instance, and the other is validating it.

        Rather than having to read the whole file, the first reads a bit and the second processes a bit and the first reads a bit more and so on. Both retain their own state across calls to the other. Think coroutines; a consumer and producer that each retain their running state, whilst switching control between themselves


        Examine what is said, not who speaks.
        Silence betokens consent.
        Love the truth but pardon error.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://422368]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2019-11-14 03:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (76 votes). Check out past polls.

    Notices?