[squeak-dev] The Trunk: Collections-eem.724.mcz

Eliot Miranda eliot.miranda at gmail.com
Mon Dec 5 04:56:02 UTC 2016


Hi Levente,

On Sat, Dec 3, 2016 at 10:33 AM, Levente Uzonyi <leves at caesar.elte.hu>
wrote:

> Hi Eliot,
>
> Does this mean that using a temporary has become quicker than sending
> #size on Spur VMs?
> On non-Spur Cog the latter used to take less time, which was why I didn't
> use another temporary variable.


There is /no way/ a single instruction to read a temporary is slower than
the tens of instructions needed to derive the size of an Array.  There must
have been something wrong with your measurements.


>
>
> Levente
>
>
> On Sat, 3 Dec 2016, commits at source.squeak.org wrote:
>
> Eliot Miranda uploaded a new version of Collections to project The Trunk:
>> http://source.squeak.org/trunk/Collections-eem.724.mcz
>>
>> ==================== Summary ====================
>>
>> Name: Collections-eem.724
>> Author: eem
>> Time: 3 December 2016, 9:30:36.13835 am
>> UUID: 83cb6b85-2b47-4c92-a953-e3787a19d53b
>> Ancestors: Collections-eem.723
>>
>> The various scanFor: and scanForEmptySlotFor: implementations only need
>> to access the size of their array once.
>>
>> Fix protocol for an #=
>>
>> =============== Diff against Collections-eem.723 ===============
>>
>> Item was changed:
>>  ----- Method: Dictionary>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ anObject =
>> element key ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: HashedCollection>>scanForEmptySlotFor: (in category
>> 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: IdentityDictionary>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size | +  index := start := anObject
>> scaledIdentityHash \\ (size := array size) + 1.
>> -       | index start | -       index := start := anObject
>> scaledIdentityHash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ element key ==
>> anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: IdentityDictionary>>scanForEmptySlotFor: (in category
>> 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: IdentitySet>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ element
>> enclosedSetElement == anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: IdentitySet>>scanForEmptySlotFor: (in category 'private')
>> -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: KeyedIdentitySet>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ (keyBlock
>> value: element enclosedSetElement) == anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: KeyedIdentitySet>>scanForEmptySlotFor: (in category
>> 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: KeyedSet>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ (keyBlock
>> value: element enclosedSetElement) = anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: PluggableDictionary>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> -       | index start |
>>         index := start := (hashBlock
>>                 ifNil: [ anObject hash ]
>> +               ifNotNil: [ hashBlock value: anObject ]) \\ (size :=
>> array size) + 1.
>> -               ifNotNil: [ hashBlock value: anObject ]) \\ array size +
>> 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [
>>                         equalBlock
>>                                 ifNil: [ element key = anObject ]
>>                                 ifNotNil: [ equalBlock value: element key
>> value: anObject ] ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: PluggableDictionary>>scanForEmptySlotFor: (in category
>> 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> -       | index start |
>>         index := start := (hashBlock
>>                 ifNil: [ anObject hash ]
>> +               ifNotNil: [ hashBlock value: anObject ]) \\ (size :=
>> array size) + 1.
>> -               ifNotNil: [ hashBlock value: anObject ]) \\ array size +
>> 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>> + ----- Method: PluggableSet>>= (in category 'comparing') -----
>> - ----- Method: PluggableSet>>= (in category 'as yet unclassified') -----
>>  = anObject
>>         "Two sets are equal if
>>          (a) they are the same 'kind' of thing.
>>          (b) they have the same set of keys.
>>          (c) for each (common) key, they have the same value"
>>
>>         self == anObject ifTrue: [ ^true ].
>>         self species == anObject species ifFalse: [ ^false ].
>>         hashBlock = anObject hashBlock ifFalse: [ ^false ].
>>         equalBlock = anObject equalBlock ifFalse: [ ^false ].
>>         self size = anObject size ifFalse: [ ^false ].
>>         ^self allSatisfy: [ :each | anObject includes: each ]!
>>
>> Item was changed:
>>  ----- Method: PluggableSet>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> -       | index start |
>>         index := start := (hashBlock
>>                 ifNil: [ anObject hash ]
>> +               ifNotNil: [ hashBlock value: anObject ]) \\ (size :=
>> array size) + 1.
>> -               ifNotNil: [ hashBlock value: anObject ]) \\ array size +
>> 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [
>>                         equalBlock
>>                                 ifNil: [ element enclosedSetElement =
>> anObject ]
>>                                 ifNotNil: [ equalBlock value: element
>> enclosedSetElement value: anObject ] ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: PluggableSet>>scanForEmptySlotFor: (in category
>> 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> -       | index start |
>>         index := start := (hashBlock
>>                 ifNil: [ anObject hash ]
>> +               ifNotNil: [ hashBlock value: anObject ]) \\ (size :=
>> array size) + 1.
>> -               ifNotNil: [ hashBlock value: anObject ]) \\ array size +
>> 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: Set>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ anObject =
>> element enclosedSetElement ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: WeakIdentityKeyDictionary>>scanFor: (in category
>> 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either a nil
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == nil or: [ element key ==
>> anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: WeakIdentityKeyDictionary>>scanForEmptySlotFor: (in
>> category 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by a nil). Answer the index of that slot. This method will be
>> overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject scaledIdentityHash \\ (size := array
>> size) + 1.
>> -       | index start |
>> -       index := start := anObject scaledIdentityHash \\ array size + 1.
>>         [
>>                 (array at: index) ifNil: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: WeakSet>>scanFor: (in category 'private') -----
>>  scanFor: anObject
>>         "Scan the key array for the first slot containing either flag
>> (indicating an empty slot) or an element that matches anObject. Answer the
>> index of that slot or raise an error if no slot is found. This method will
>> be overridden in various subclasses that have different interpretations for
>> matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == flag or: [ element
>> enclosedSetElement = anObject ])
>>                         ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>> Item was changed:
>>  ----- Method: WeakSet>>scanForEmptySlotFor: (in category 'private') -----
>>  scanForEmptySlotFor: anObject
>>         "Scan the key array for the first slot containing an empty slot
>> (indicated by flag or a nil). Answer the index of that slot. This method
>> will be overridden in various subclasses that have different
>> interpretations for matching elements."
>>
>> +       | index start size |
>> +       index := start := anObject hash \\ (size := array size) + 1.
>> -       | index start |
>> -       index := start := anObject hash \\ array size + 1.
>>         [
>>                 | element |
>>                 ((element := array at: index) == flag or: [ element ==
>> nil ]) ifTrue: [ ^index ].
>> +               (index := index \\ size + 1) = start ] whileFalse.
>> -               (index := index \\ array size + 1) = start ] whileFalse.
>>         self errorNoFreeSpace!
>>
>
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20161204/599ecdce/attachment.html>


More information about the Squeak-dev mailing list