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

Re: Garbage collection at subroutine return

by liverpole (Monsignor)
on Feb 15, 2007 at 13:38 UTC ( [id://600202]=note: print w/replies, xml ) Need Help??


in reply to Garbage collection at subroutine return

Hi tcarmeli,

Sure, why not declare the hash outside of the subroutine, so that its scope doesn't cause it to be garbage-collected?  You're obviously not using the hash anyway:

#!/usr/bin/perl -w use strict; use warnings; my $func_done; my $func_return; my $max=1000000; my %myhash; DoIt($max); $func_return = (times)[0]; printf "Size of myhash is %d\n", 0 + keys %myhash; printf "Return took %.4f CPU seconds\n", $func_return - $func_done; sub DoIt{ my $limit=shift; my $i; foreach $i (0..$limit){ $myhash{$i}=1; } $func_done = (times)[0]; return; }

But it sounds like you may have an XY problem.  What is your real goal here?


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Garbage collection at subroutine return
by tcarmeli (Beadle) on Feb 15, 2007 at 13:53 UTC
    This is actually an excellent solution I somehow ignored, as I tend to avoid global variables as a 1st instinct.

    For the other questions and remarks:
    I am not suprised by this phenomena, although I did not imagine such a penalty.
    I use a sub that uses some huge data structures and is being invoked quite a lot. This code is of course just a example of the principle.
      Hi tcarmeli,

      You don't need to have it global, just have it scoped outside the sub.

      For example:

      { my %myhash; sub DoIt{ my $limit=shift; my $i; # really, what you'd do here is just init the # as-yet uninitialized part foreach $i ((scalar keys %myhash)..$limit){ $myhash{$i}=1; } $func_done = (times)[0]; return; } } # scope for %myHash
      Of course, I haven't tried this, but I think it'd do what you want, and handle the case where it's called twice with different values of $limit.

      Mike

        No need to really even do that. Use references and have DoIt return the reference:

        my $h = DoIt( $max ); sub DoIt{ my $limit=shift; my $i; my $myhash; foreach $i (0..$limit){ $myhash->{$i}=1; } $func_done = (times)[0]; $myhash; }
        That prevents the reference count from being decremented and hence no gc (well at least tell the end of the block containing $h)

        -derby

      You might consider using OO techniques to "hide" the global. Make the global into a data member (bless it) and the sub into a method. Of course you then get hit with access costs so you may not end up with a performance win. However OO can help refactor code and that may be a key to unlocking the real problem.


      DWIM is Perl's answer to Gödel

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2024-04-25 07:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found