i feel dumb / Pharo3 > OrderedCollection >> do:

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

i feel dumb / Pharo3 > OrderedCollection >> do:

Pharo Smalltalk Users mailing list
I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Marcus Denker-4

On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:


Date: 18 Feb 2015 18:12:33 CET
Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
From: Cameron Sanders <[hidden email]>
To: Any question about pharo is welcome <[hidden email]>


I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


shallowCopy is not enough… OrderedCollection is made up of an internal array.

#copy does the right thing, just copies the array:

postCopy
array := array copy

and for Array, copy is a shallowCopy.

Marcus



Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

S Krish

I presumed shallowCopy for literal arrays / OrderedCollection should have been a true copy. Perhaps need to understand this..

shallowCopy
    "Answer a copy of the receiver which shares the receiver's instance variables. It should never be overridden. I'm invoked from the copy template method. Subclasses that need to specialize the copy should specialize the postCopy hook method."
   ...
    <primitive: 148>
    class := self class.
    class isVariable
        ifTrue:
            [...   newObject := class basicNew: index. ....]
        ifFalse: [newObject := class basicNew].
    ..
        whileTrue:
            [newObject instVarAt: index put: (self instVarAt: index).
           ...
    ^ newObject

On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <[hidden email]> wrote:

On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:


Date: 18 Feb 2015 18:12:33 CET
Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
From: Cameron Sanders <[hidden email]>
To: Any question about pharo is welcome <[hidden email]>


I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


shallowCopy is not enough… OrderedCollection is made up of an internal array.

#copy does the right thing, just copies the array:

postCopy
array := array copy

and for Array, copy is a shallowCopy.

Marcus




Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Marcus Denker-4

On 20 Feb 2015, at 06:23, S Krish <[hidden email]> wrote:


I presumed shallowCopy for literal arrays / OrderedCollection should have been a true copy. Perhaps need to understand this..


OrderdCollection is not just one object, but it holds on to an Array that has it’s content. You copy the outside collection object, but share
the Array.

shallowCopy
    "Answer a copy of the receiver which shares the receiver's instance variables. It should never be overridden. I'm invoked from the copy template method. Subclasses that need to specialize the copy should specialize the postCopy hook method."
   ...
    <primitive: 148>
    class := self class.
    class isVariable
        ifTrue:
            [...   newObject := class basicNew: index. ....]
        ifFalse: [newObject := class basicNew].
    ..
        whileTrue:
            [newObject instVarAt: index put: (self instVarAt: index).
           ...
    ^ newObject

On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <[hidden email]> wrote:

On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:


Date: 18 Feb 2015 18:12:33 CET
Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
From: Cameron Sanders <[hidden email]>
To: Any question about pharo is welcome <[hidden email]>


I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


shallowCopy is not enough… OrderedCollection is made up of an internal array.

#copy does the right thing, just copies the array:

postCopy
array := array copy

and for Array, copy is a shallowCopy.

Marcus





Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Clément Béra
It depends on your OrderedCollection implementation.

OrderedCollection has a variable size in memory. When instantiated, it has for example 10 slots, and if you have more than 10 objects, it needs to change its size to hold more slots. 

The current implementation relies on an indirection to an array, when the array overflows, the orderedCollection allocates a new bigger array and copy the slots from the existing array. There are some heuristics on array size to avoid having to grow the array too often.

If you want the shallowCopy to work, you have to use the old implementation of OrderedCollection, which encodes in its field directly the values it holds. In this case however when the collection overflows you create a new orderedCollection so you need to use #become: to migrate references to the old orderedCollection to the new one. This used to be a bad idea because the become primitive was slow, but since we have Spur, it may be relevant to look at it again. This old implementation is more memory efficient too.

2015-02-20 8:05 GMT+01:00 Marcus Denker <[hidden email]>:

On 20 Feb 2015, at 06:23, S Krish <[hidden email]> wrote:


I presumed shallowCopy for literal arrays / OrderedCollection should have been a true copy. Perhaps need to understand this..


OrderdCollection is not just one object, but it holds on to an Array that has it’s content. You copy the outside collection object, but share
the Array.

shallowCopy
    "Answer a copy of the receiver which shares the receiver's instance variables. It should never be overridden. I'm invoked from the copy template method. Subclasses that need to specialize the copy should specialize the postCopy hook method."
   ...
    <primitive: 148>
    class := self class.
    class isVariable
        ifTrue:
            [...   newObject := class basicNew: index. ....]
        ifFalse: [newObject := class basicNew].
    ..
        whileTrue:
            [newObject instVarAt: index put: (self instVarAt: index).
           ...
    ^ newObject

On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <[hidden email]> wrote:

On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:


Date: 18 Feb 2015 18:12:33 CET
Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
From: Cameron Sanders <[hidden email]>
To: Any question about pharo is welcome <[hidden email]>


I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


shallowCopy is not enough… OrderedCollection is made up of an internal array.

#copy does the right thing, just copies the array:

postCopy
array := array copy

and for Array, copy is a shallowCopy.

Marcus






Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Mariano Martinez Peck


On Fri, Feb 20, 2015 at 5:48 AM, Clément Bera <[hidden email]> wrote:
It depends on your OrderedCollection implementation.

OrderedCollection has a variable size in memory. When instantiated, it has for example 10 slots, and if you have more than 10 objects, it needs to change its size to hold more slots. 


I thought that was the case too, but I cannot find in code what you say. OrderedCollection nor it's parents are created with #variableSubclass... As you can see, "OrderedCollection isVariable" answers false. So where is that "variable size in memory" ?

Thanks, 
 
The current implementation relies on an indirection to an array, when the array overflows, the orderedCollection allocates a new bigger array and copy the slots from the existing array. There are some heuristics on array size to avoid having to grow the array too often.

If you want the shallowCopy to work, you have to use the old implementation of OrderedCollection, which encodes in its field directly the values it holds. In this case however when the collection overflows you create a new orderedCollection so you need to use #become: to migrate references to the old orderedCollection to the new one. This used to be a bad idea because the become primitive was slow, but since we have Spur, it may be relevant to look at it again. This old implementation is more memory efficient too.

2015-02-20 8:05 GMT+01:00 Marcus Denker <[hidden email]>:

On 20 Feb 2015, at 06:23, S Krish <[hidden email]> wrote:


I presumed shallowCopy for literal arrays / OrderedCollection should have been a true copy. Perhaps need to understand this..


OrderdCollection is not just one object, but it holds on to an Array that has it’s content. You copy the outside collection object, but share
the Array.

shallowCopy
    "Answer a copy of the receiver which shares the receiver's instance variables. It should never be overridden. I'm invoked from the copy template method. Subclasses that need to specialize the copy should specialize the postCopy hook method."
   ...
    <primitive: 148>
    class := self class.
    class isVariable
        ifTrue:
            [...   newObject := class basicNew: index. ....]
        ifFalse: [newObject := class basicNew].
    ..
        whileTrue:
            [newObject instVarAt: index put: (self instVarAt: index).
           ...
    ^ newObject

On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <[hidden email]> wrote:

On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:


Date: 18 Feb 2015 18:12:33 CET
Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
From: Cameron Sanders <[hidden email]>
To: Any question about pharo is welcome <[hidden email]>


I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.

This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.

Thanks in advance. ... Maybe I just need more coffee.
-Cam

| a  |
a := {  #a. #b. #c. #d. } asOrderedCollection.
a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
a size


shallowCopy is not enough… OrderedCollection is made up of an internal array.

#copy does the right thing, just copies the array:

postCopy
array := array copy

and for Array, copy is a shallowCopy.

Marcus









--
Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Sven Van Caekenberghe-2
(class side)

#new:

(instance side)

#growAtFirst
#growAtLast
#makeRoomAtFirst
#makeRoomAtLast

       

> On 23 Feb 2015, at 21:15, Mariano Martinez Peck <[hidden email]> wrote:
>
>
>
> On Fri, Feb 20, 2015 at 5:48 AM, Clément Bera <[hidden email]> wrote:
> It depends on your OrderedCollection implementation.
>
> OrderedCollection has a variable size in memory. When instantiated, it has for example 10 slots, and if you have more than 10 objects, it needs to change its size to hold more slots.
>
>
> I thought that was the case too, but I cannot find in code what you say. OrderedCollection nor it's parents are created with #variableSubclass... As you can see, "OrderedCollection isVariable" answers false. So where is that "variable size in memory" ?
>
> Thanks,
>  
> The current implementation relies on an indirection to an array, when the array overflows, the orderedCollection allocates a new bigger array and copy the slots from the existing array. There are some heuristics on array size to avoid having to grow the array too often.
>
> If you want the shallowCopy to work, you have to use the old implementation of OrderedCollection, which encodes in its field directly the values it holds. In this case however when the collection overflows you create a new orderedCollection so you need to use #become: to migrate references to the old orderedCollection to the new one. This used to be a bad idea because the become primitive was slow, but since we have Spur, it may be relevant to look at it again. This old implementation is more memory efficient too.
>
> 2015-02-20 8:05 GMT+01:00 Marcus Denker <[hidden email]>:
>
>> On 20 Feb 2015, at 06:23, S Krish <[hidden email]> wrote:
>>
>>
>> I presumed shallowCopy for literal arrays / OrderedCollection should have been a true copy. Perhaps need to understand this..
>>
>
> OrderdCollection is not just one object, but it holds on to an Array that has it’s content. You copy the outside collection object, but share
> the Array.
>
>> shallowCopy
>>     "Answer a copy of the receiver which shares the receiver's instance variables. It should never be overridden. I'm invoked from the copy template method. Subclasses that need to specialize the copy should specialize the postCopy hook method."
>>    ...
>>     <primitive: 148>
>>     class := self class.
>>     class isVariable
>>         ifTrue:
>>             [...   newObject := class basicNew: index. ....]
>>         ifFalse: [newObject := class basicNew].
>>     ..
>>         whileTrue:
>>             [newObject instVarAt: index put: (self instVarAt: index).
>>            ...
>>     ^ newObject
>>
>> On Wed, Feb 18, 2015 at 10:52 PM, Marcus Denker <[hidden email]> wrote:
>>
>>> On 18 Feb 2015, at 18:13, Cameron Sanders via Pharo-users <[hidden email]> wrote:
>>>
>>>
>>> Date: 18 Feb 2015 18:12:33 CET
>>> Subject: i feel dumb / Pharo3 > OrderedCollection >> do:
>>> From: Cameron Sanders <[hidden email]>
>>> To: Any question about pharo is welcome <[hidden email]>
>>>
>>>
>>> I must be making some silly error here that i cannot see clearly. Why does the following leave anything in the list 'a'? Run it in a workspace. With or without the shallowCopy, i am left with a list with half of the elements in it. Always half.
>>>
>>> This version of Pharo3 (21.0) was downloaded last week. I am running on a Mac.
>>>
>>> Thanks in advance. ... Maybe I just need more coffee.
>>> -Cam
>>>
>>> | a  |
>>> a := {  #a. #b. #c. #d. } asOrderedCollection.
>>> a shallowCopy do: [ :item | (a includes: item) ifTrue: [ a remove: item ]].
>>> a size
>>>
>>
>> shallowCopy is not enough… OrderedCollection is made up of an internal array.
>>
>> #copy does the right thing, just copies the array:
>>
>> postCopy
>> array := array copy
>>
>> and for Array, copy is a shallowCopy.
>>
>> Marcus
>>
>>
>>
>>
>
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com


Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Marcus Denker-4
In reply to this post by Mariano Martinez Peck

On 23 Feb 2015, at 21:15, Mariano Martinez Peck <[hidden email]> wrote:



On Fri, Feb 20, 2015 at 5:48 AM, Clément Bera <[hidden email]> wrote:
It depends on your OrderedCollection implementation.

OrderedCollection has a variable size in memory. When instantiated, it has for example 10 slots, and if you have more than 10 objects, it needs to change its size to hold more slots. 


I thought that was the case too, but I cannot find in code what you say.

What Clement says is that *conceptionally* it has a variyng size. The current implementation uses an internal Array, as he describes:
 
The current implementation relies on an indirection to an array, when the array overflows, the orderedCollection allocates a new bigger array and copy the slots from the existing array. There are some heuristics on array size to avoid having to grow the array too often.

If you want the shallowCopy to work, you have to use the old implementation of OrderedCollection, which encodes in its field directly the values it holds. In this case however when the collection overflows you create a new orderedCollection so you need to use #become: to migrate references to the old orderedCollection to the new one. This used to be a bad idea because the become primitive was slow, but since we have Spur, it may be relevant to look at it again. This old implementation is more memory efficient too.


And then, with the new fast #become:, we can go back the the old implementation and grow OrderedCollection using #become:, which would mean that we would
not need two objects anymore… 

Marcus
Reply | Threaded
Open this post in threaded view
|

Re: i feel dumb / Pharo3 > OrderedCollection >> do:

Stephan Eggermont-3
On 24/02/15 08:05, Marcus Denker wrote:
> And then, with the new fast #become:, we can go back the the old
> implementation and grow OrderedCollection using #become:, which would
> mean that we would
> not need two objects anymore…

Until the collection grows large. Then we need some chunked format,
to avoid copying large blocks of memory.

Stephan