On 05.10.2011 11:19, Henrik Sperre Johansen wrote:
On 05.10.2011 01:59, Nicolas Cellier wrote:

However, maybe Mariano is searching for tight inner loop optimization
(we can only guess, because he didn't tell, he should have).
In this case, using ifFalse: is good: because it is inlined by
Compiler, it avoids a BlockClosure creation.
But above code will cost two lookup in both branch, so it will be
pretty bad too, depending on hash evaluation cost and collision rate,
in a majority of cases, worse than block creation time.

You could make at:ifAbsentPut: do single lookup, at the cost of using cull: (with the scanned for index) in at:ifAbsent: . Sort of restricts what you can pass to at:ifAbsent: though, (not that I found any not using a block in a quick scan of senders, nor did my image crash)
and the runtime really didn't improve that much.
Here's the .cs for those interested, btw.

Cheers,
Henry
'From Pharo1.4a of ''16 June 2011'' [Latest update: #14153] on 5 October 2011 
at 11:20:21 am'!

!HashedCollection methodsFor: 'private' stamp: 'HenrikSperreJohansen 10/4/2011 
13:55'!
atNewIndex: index put: anObject
        array at: index put: anObject.
        tally := tally + 1.
        self fullCheck.
        ^anObject! !

!Dictionary methodsFor: 'accessing' stamp: 'HenrikSperreJohansen 10/4/2011 
13:58'!
at: key ifAbsent: aBlock 
        "Answer the value associated with the key or, if key isn't found,
        answer the result of evaluating aBlock."
        | slotIndex |
        slotIndex := self scanFor: key.
        ^(array at: slotIndex) 
                        ifNil: [aBlock cull: slotIndex]
                        ifNotNil: [:assoc | assoc value ] 
                        ! !

!Dictionary methodsFor: 'accessing' stamp: 'HenrikSperreJohansen 10/4/2011 
13:59'!
at: key ifPresent: aBlock
        "Lookup the given key in the receiver. If it is present, answer the 
value of evaluating the given block with the value associated with the key. 
Otherwise, answer nil."

        ^(array at: (self scanFor: key))
                ifNotNil: [:assoc | aBlock cull: assoc value]! !

!Dictionary methodsFor: 'accessing' stamp: 'HenrikSperreJohansen 10/4/2011 
13:57'!
at: key ifAbsentPut: aBlock 
        "Return the value at the given key. 
        If key is not included in the receiver store the result 
        of evaluating aBlock as new value."

        ^ self at: key ifAbsent: [:index | (self atNewIndex: index put: key -> 
aBlock value) value]! !

Reply via email to