The Trunk: Collections-ul.679.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Collections-ul.679.mcz

commits-2
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!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Collections-ul.679.mcz

Nicolas Cellier


2016-03-08 21:06 GMT+01:00 <[hidden email]>:
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

and/or in ByteString
+       anObject isCharacter ifFalse: [ ^0 ].
+       anObject asInteger < 255 ifFalse: [ ^0 ].
         snip...



Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Collections-ul.679.mcz

Nicolas Cellier


2016-03-08 21:18 GMT+01:00 Nicolas Cellier <[hidden email]>:


2016-03-08 21:06 GMT+01:00 <[hidden email]>:
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

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 ].



Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Collections-ul.679.mcz

Levente Uzonyi
On Tue, 8 Mar 2016, Nicolas Cellier wrote:

>
>
> 2016-03-08 21:18 GMT+01:00 Nicolas Cellier <[hidden email]>:
>
>
>       2016-03-08 21:06 GMT+01:00 <[hidden email]>:
>             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). :)

>
> 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

>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Collections-ul.679.mcz

Eliot Miranda-2
Hi Levente,


> On Mar 8, 2016, at 1:21 PM, Levente Uzonyi <[hidden email]> wrote:
>
>> On Tue, 8 Mar 2016, Nicolas Cellier wrote:
>>
>> 2016-03-08 21:18 GMT+01:00 Nicolas Cellier <[hidden email]>:
>>
>>      2016-03-08 21:06 GMT+01:00 <[hidden email]>:
>>            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
>
>

Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Collections-ul.679.mcz

Levente Uzonyi
Hi Eliot,

On Wed, 16 Mar 2016, Eliot Miranda wrote:

> Hi Levente,
>
>

snip

>>
>> 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.

It would probably be quicker, but actually I didn't want to optimize this
rarely used method as much as it would have been possible. Were I to do
that, I would even use primitiveIndexOfAsciiInString for longer
ByteStrings, ByteSymbols and ByteArrays.

The only reason I tweaked these methods is that I realized that it was
quite slow while serializing json objects. For our code, which runs on
Squeak 4.4, this change had no effect anyway, so I just avoided these
sends there altogether.

Levente

>
>>
>>> 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
>>
>>
>
>