Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

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

by BrowserUk (Pope)
on Jan 14, 2005 at 20:58 UTC ( #422385=note: print w/replies, xml ) Need Help??


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

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.

Replies are listed 'Best First'.
Re^8: Who's a thief? (No memory growth with magic goto)
by demerphq (Chancellor) on Jan 15, 2005 at 09:54 UTC

    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.

        If you're not afraid to call it like it is, then it sure is possible. It did take three refactors until I got it as clear as this, though:

        #!/usr/bin/perl use strict; use warnings; my( $count1, $count2 ); sub a1 { a2b2( --$_[ 1 ], 1 ); a2b2( $_[ 0 ], !1 ); } sub a2b2 { $_[ 1 ] or goto a2; { b2: $count2++; a2: $count1++; $_[ 0 ]-- and redo; } } my( $n1, $n2 ) = ( 100, 50 ); a1( $n1, $n2 ); print "c1: $count1; c2: $count2\n";

        Makeshifts last the longest.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (8)
As of 2019-11-22 15:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Strict and warnings: which comes first?



    Results (113 votes). Check out past polls.

    Notices?