develooper Front page | perl.perl5.porters | Postings from October 2002

Re: Collections

Thread Previous | Thread Next
From:
Slaven Rezic
Date:
October 2, 2002 00:50
Subject:
Re: Collections
Message ID:
87elb9jo4l.fsf@vran.herceg.de
Christian Jaeger <christian.jaeger@sl.ethz.ch> writes:

> At 22:45 Uhr +0100 29.09.2002, Nicholas Clark wrote:
> >Based on an idea H Merijn Brand told me, try using try using the string
> >generated by (pack 'I', $obj) as your hash key, and see if that helps.
> 
> (Benjamin Goldberg had already suggested that to me in private mail.)
> 
> Here are some numbers: (test script see below; the script has been 
> terminated by Ctl-C, 0.2s have been subtracted from the output of the 
> "time" value to accomodate for the perl startup time; perl5.6.1 linux 
> ppc)
> 
> key                         cpu user  ~memory (rss)
> --------------------------- --------- ------------
> id ($_ or $_->{iter} resp.) 0m4.460s  30MB
> pack("I",$obj) without iter 0m4.540s  28MB          *)
> stringid                    0m4.720s  29MB
> pack("I",$obj)              0m5.190s  28MB
> pack("I",id)                0m5.840s  28MB
> Devel::Pointer & in value   0m6.290s  32MB          **)
> Devel::Pointer & selfref.   0m6.820s  34MB          ***)
> $obj                        0m8.730s  28MB
> $obj+0                      0m10.590s 28MB
> Tie::RefHash                0m35.790s 53MB
> 
> *) no iter=>$_ is put into the hashes, and instead of adding 
> $_->{iter} to $total, just 1 is added.
> 
> **) $bucket->{pack "I",$obj} = $obj; ...; $smallbucket->{pack "I",$obj}=undef;
> 
> ***) $bucket->{pack "I",$obj}= undef; $obj->{self}=$obj;
> 
> The tests **) and ***) use Devel::Pointer::unsmash_hv(unpack "I",$_) 
> to get from the key back to the object.
> 
> There's one important issue though with this approach: since the keys 
> are no SV's anymore, the refcount of the object would drop to zero 
> and the object would get freed. The subsequent unsmash_hv would 
> recreate an SV which doesn't exist anymore and then lead to a 
> segfault. So I had to make sure the refcount doesn't drop to zero; in 
> ** I did this by storing the object as good old hash value as well, 
> in *** I created a circle to itself.

Or just increment the reference count yourself, either with
Internals::SvREFCNT or with a small chunk of C code:

#!/usr/bin/perl -w
use Devel::Pointer;
use strict;

my $ptr;
{
    my $x1 = [1,2,3,4];
    Internals::SvREFCNT($x1, Internals::SvREFCNT($x1)+2);
    $ptr = address_of($x1);
}

my $x1_again = deref($ptr);
require Data::Dumper; print STDERR "Line " . __LINE__ . ", File: " . __FILE__ . "\n" . Data::Dumper->new([$x1_again],[])->Indent(1)->Useqq(1)->Dump; # XXX

__END__

> So Devel::Pointer doesn't really 
> work for this purpose.
> 

Regards,
	Slaven

-- 
Slaven Rezic - slaven.rezic@berlin.de

    tksm - Perl/Tk program for searching and replacing in multiple files
    http://ptktools.sourceforge.net/#tksm

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About