[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