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