in reply to Re: Garbage collection at subroutine return
in thread Garbage collection at subroutine return

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.
  • Comment on Re^2: Garbage collection at subroutine return

Replies are listed 'Best First'.
Re^3: Garbage collection at subroutine return
by RMGir (Prior) on Feb 15, 2007 at 15:14 UTC
    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
        True, but slightly different.

        Your approach is correct if the goal is to construct a one-off structure and pass it back to the caller, surviving until the caller is done with it. Useful if the function generates some kind of custom hash mapping, for example.

        My approach is correct if the intent of myhash is to be some kind of persistent structure internal to the mechanics of DoIt, perhaps some kind of memoization cache or other internal structure.

        They're both useful, it all depends on what the original intent was (which is a bit hard to discern from the question).


        Mike
Re^3: Garbage collection at subroutine return
by GrandFather (Saint) on Feb 15, 2007 at 19:48 UTC

    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