[squeak-dev] The Trunk: Collections-ul.679.mcz

Eliot Miranda eliot.miranda at gmail.com
Wed Mar 16 16:09:38 UTC 2016


Hi Levente,


> On Mar 8, 2016, at 1:21 PM, Levente Uzonyi <leves at caesar.elte.hu> wrote:
> 
>> On Tue, 8 Mar 2016, Nicolas Cellier wrote:
>> 
>> 2016-03-08 21:18 GMT+01:00 Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>:
>> 
>>      2016-03-08 21:06 GMT+01:00 <commits at source.squeak.org>:
>>            Levente Uzonyi uploaded a new version of Collections to project The Trunk:
>>            http://source.squeak.org/trunk/Collections-ul.679.mcz
>> 
>>            ==================== Summary ====================
>> 
>>            Name: Collections-ul.679
>>            Author: ul
>>            Time: 8 March 2016, 5:24:30.010047 pm
>>            UUID: 9f4b6193-4632-48c7-a99f-ee37923bf28b
>>            Ancestors: Collections-eem.678
>> 
>>            #occurrencesOf: revamp:
>>            - optimized Bag's implementation
>>            - added optimized versions to ArrayedCollection, String and ByteArray
>> 
>>            =============== Diff against Collections-eem.678 ===============
>> 
>>            Item was added:
>>            + ----- Method: ArrayedCollection>>occurrencesOf: (in category 'testing') -----
>>            + occurrencesOf: anObject
>>            +       "Answer how many of the receiver's elements are equal to anObject. Optimized version."
>>            +
>>            +       | tally |
>>            +       tally := 0.
>>            +       1 to: self size do: [ :index |
>>            +               (self at: index) = anObject ifTrue: [ tally := tally + 1 ] ].
>>            +       ^tally!
>> 
>>            Item was changed:
>>              ----- Method: Bag>>occurrencesOf: (in category 'testing') -----
>>            + occurrencesOf: anObject
>>            +       "Answer how many of the receiver's elements are equal to anObject. Optimized version."
>>            - occurrencesOf: anObject
>>            -       "Refer to the comment in Collection|occurrencesOf:."
>> 
>>            +       ^contents at: anObject ifAbsent: 0!
>>            -       (self includes: anObject)
>>            -               ifTrue: [^contents at: anObject]
>>            -               ifFalse: [^0]!
>> 
>>            Item was added:
>>            + ----- Method: ByteArray>>occurrencesOf: (in category 'as yet unclassified') -----
>>            + occurrencesOf: anObject
>>            +       "Answer how many of the receiver's elements are equal to anObject. Optimized version."
>>            +
>>            +       | tally |
>>            +       anObject isInteger ifFalse: [ ^0 ].
>>            +       anObject negative ifTrue: [ ^0 ].
>>            +       anObject > 255 ifTrue: [ ^0 ].
>>            +       tally := 0.
>>            +       1 to: self size do: [ :index |
>>            +               (self at: index) = anObject ifTrue: [ tally := tally + 1 ] ].
>>            +       ^tally!
>> 
>>            Item was added:
>>            + ----- Method: String>>occurrencesOf: (in category 'testing') -----
>>            + occurrencesOf: anObject
>>            +       "Answer how many of the receiver's elements are equal to anObject. Optimized version."
>>            +
>>            +       | tally |
>>            +       anObject isCharacter ifFalse: [ ^0 ].
>>            +       tally := 0.
>>            +       1 to: self size do: [ :index |
>>            +               (self at: index) == anObject ifTrue: [ tally := tally + 1 ] ].
>>            +       ^tally!
>> it could have been
>> +       anObject isCharacter ifFalse: [ ^0 ].
>> +       ^super occurrencesOf: anObject
> 
> But this way we save a message send, and (ab)use the fact that #== is faster than #= and is still correct (in Spur). :)

Have you checked whether #== is faster in ByteArray too?  The JIT doesn't always inline SmallInteger code for special selectors since they don't always predict SmallIntegers well.  The JIT inlines #= & #~= when either the receiver or arg are literal integers, but neither are above so there will be no inlining.  There will be with #==, and that makes the ifTrue: much faster because it gets optimised to a conditional jump instruction, not a test in true or false.

> 
>> and/or in ByteString
>> +       anObject isCharacter ifFalse: [ ^0 ].
>> +       anObject asInteger < 255 ifFalse: [ ^0 ].
>>          snip...
>> Hem
>> +       anObject asInteger <= 255 ifFalse: [ ^0 ].
>> or
>> +       anObject asInteger < 256 ifFalse: [ ^0 ].
>> or
>> +       anObject asInteger > 255 ifTrue: [ ^0 ].
> 
> Right, but then you'd feel like adding it to ByteSymbol as well.
> 
> Levente
> 
> 


More information about the Squeak-dev mailing list