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