[ENH] Ten Percent Faster Morphic! (with conversion)
Stephen Pair
spair at acm.org
Tue Aug 6 17:41:07 UTC 2002
But you could only do that for identity based, hashed collections right?
Otherwise, the primitive would need to send #= somehow. But, a
primitive for scanFor: that was passed the hash, and was specific for
identity comparison might indeed be worthwhile.
So Ned...why didn't you subclass IdentityDictionary for MorphProperties?
You could have overidden #at: to scan the first few slots of the array,
and if that didn't find your target, just finish with a call to the
super implementation of #at: (assuming here that lookup is the critical
optimization and not adding/removing).
On a related note, I noticed the following code (in
IdentityDictionary>>scanFor:) that appears to spread out the hash for
identity based hashed collections:
finish > 4096
ifTrue: [hash _ anObject identityHash * (finish //
4096)]
ifFalse: [hash _ anObject identityHash].
This seems to make IdentityDictionaries perform reasonably well at
larger size (I tested with a IdentityDictionary of 10000 associations,
and it seem to perform fine). Perhaps this is not what's causing the
performance problem with Magma.
- Stephen
> -----Original Message-----
> From: squeak-dev-admin at lists.squeakfoundation.org
> [mailto:squeak-dev-admin at lists.squeakfoundation.org] On
> Behalf Of Henrik Gedenryd
> Sent: Tuesday, August 06, 2002 12:45 PM
> To: squeak-dev
> Subject: Re: [ENH] Ten Percent Faster Morphic! (with conversion)
>
>
> Stephen Pair wrote:
>
> > Exactly...for small dicts you would skip the hash and
> always start the
> > scan at 1. Of course, it all depends on the hash, and how
> frequently
> > the contents are accessed to determine just how much time
> is saved.
> > As Ned discovered, in Morphic, the savings can be
> significant. But,
> > on the other side, keeping things simple is sometimes worth
> > sacrificing a little performance.
> >
> >> I could be wrong though, and this is why I ask the above question.
> >>
> >> Henrik
> >
> > - Stephen
>
> Yes. I looked at Ned's code--I was particularly surprised
> that the loop unrolling made a significant difference--and it
> turns out it is the primitive ops in scanFor: that take time:
> checking for nil, branching in the loop, and so on, really
> small operations. No message sends or getting the hash or
> some such, just the primitive ops of the scan.
>
> So I suggest that a much simpler solution/smaller change is
> to instead add a primitive for scanFor:, to which you pass
> the hash value to use so you can use the same one also for
> regular dictionaries. It should be possible to refactor the
> code for the message lookup of the vm, in
> Interpreter>>#lookupMethodInDictionary: , into something like
> lookupKey:
> Interpreter>>key
> startingAt: index .
>
> This ought to give the same speedup as Ned's changes
> (assuming that in C the scan time is negligible), for all
> small regular and id-dictionaries, and by only adding a
> primitive for scanFor:
>
> I feel uncomfortable doing such a vm change myself. I don't
> even remember how to use an argument in a primitive...
>
> Henrik
>
>
>
More information about the Squeak-dev
mailing list
|