develooper Front page | perl.perl5.porters | Postings from April 2007

Re: Performance problems with Hash::Util::FieldHash

Thread Previous | Thread Next
Anno Siegel
April 18, 2007 10:13
Re: Performance problems with Hash::Util::FieldHash
Message ID:

On 18.04.2007, at 16:31, Jerry D. Hedden wrote:

> I began looking at adapting Object::InsideOut to using
> Hash::Util::FieldHash.  My first endeavor was to see how
> fast they were.  Much to my surprise, their performance is
> disappointing.  I compared simple get and set accessors for
> inside-out classes using field hashes, refaddr and
> stringified objects.  ...

[benchmark results]

> While field hashes do a bit better than refaddr in get
> operations, stringification is the hands down winner!  Why?

A field hash maintains a data structure in the backgroud that
supports garbage collection (and, incidentally, thread support).
The overhead amortizes against the time object destruction
takes in a normal inside-out class.  This is hard to benchmark
meaningfully because you'd have to make assumptions
about the number of field accesses during the lifetime of
an object.

> I tried to speed things up a bit by borrowing the trick from
> blead 28961, and replaced HUF_id with
>    SV* HUF_id(SV* ref, NV cookie) {
>        UV id = PTR2UV(SvRV(ref));
>        return sv_2mortal(newSVpvn((char *)&id, sizeof(id)));
>    }
> This only have about a 10% improvement:

Yes, that's why I don't use this optimization in preferance to
printable keys that are compatible with refaddr()-generated


> And, of course, all this pales in comparison to what
> Object::InsideOut already does.

[benchmarks showing OIO up to 990% faster than field hashes]

Well... OIO objects store their id in their body (a scalar
ref).  That speeds things up considerably, but at a cost.
A true inside-out class doesn't care what the body of
the underlying object is, it can access its fields with
any blessed (and even unblessed) ref. That gives an
additional leeway in inheritance situations that I don't
want to miss.  An OIO object must *be* a scalar which
has siginificant content, so it can't be supplanted by

> While I fully appreciate the significance of the work done
> by Anno, unless something drastic can be done to improve
> their performance, there doesn't seem to be any reason to
> bother trying to use field hashes.

My  primary goal in creating FieldHash was convenience,
not speed.  I admit I had hoped for better performance,
but settled for correctness :)  Field access doesn't dominate
class performance in all cases.  If it does, you probably
want a data base, not a class :)

There is a speed hack that brings the performance of
field hashes to better-than-refaddr, but not as fast as
stringification (on my machine).  I'm not using it because
it changes the behavior in a subtle way.  (Garbage
collection could be bypassed if you use the refaddr of
an object as a *string* hash key before first presenting
the object as such.  That won't happen in the intended
usage, but it's a weak point.)

A big time-saver would probably be to implement field
hashes in perl core instead of using uvar magic.  I don't
think the time has come for that, if it ever does.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About