Implementing lazy loading for expandable collections
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG (http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this: - my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work. Iâll share some memory monitoring as soon as I have something significant (only just rolled it out). Big thanks to Alex for his talk and the cool work he and his students did! Cheers, Max
On 2014-09-19 11:35, Max Leske wrote:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason).
I might be a bit fundamentalistic, but shouldn't this (a using class making assumptions about the objects it's using) be considered a bug by object oriented standards? Best regards Markus
2014-09-19 13:55 GMT+02:00 Markus Fritsche <mfritsche@reauktion.de>:
On 2014-09-19 11:35, Max Leske wrote:
- my implementation requires an extra instance variable in
OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason).
I might be a bit fundamentalistic, but shouldn't this (a using class making assumptions about the objects it's using) be considered a bug by object oriented standards?
Best regards Markus
It's not the using class per se. It's that MC is using a serialization framework sensitive to internal object representation (number/order of ivars). The question is this one: - would using FUEL would have resolved the problem or not? - wouldn't a serialization using message sends to reconstruct the objects be more robust (future proof)? Of course the later requires the maintenance of a well defined API, so the robstness is relative. But at least, it would respect the object paradigm a bit more. Nicolas
On 19.09.2014, at 14:06, Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com> wrote:
2014-09-19 13:55 GMT+02:00 Markus Fritsche <mfritsche@reauktion.de>: On 2014-09-19 11:35, Max Leske wrote:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason).
I might be a bit fundamentalistic, but shouldn't this (a using class making assumptions about the objects it's using) be considered a bug by object oriented standards?
Best regards Markus
It's not the using class per se. It's that MC is using a serialization framework sensitive to internal object representation (number/order of ivars).
IIRC, MC counts the number of inst vars in the implementation that is being loaded and then assumes that the current implementation has the same number of fields. It might actually be quite easy to simply use the min of the number of instance variables and ignore the rest. However, that would not address the problem of modified variable position (which is a problem at least in theory).
The question is this one: - would using FUEL would have resolved the problem or not?
Partly. You could tell Fuel to migrate to the new layout dynamically which would allow reading of the old format as well as reading and writing of the new format. It wouldnât be exactly âniceâ though.
- wouldn't a serialization using message sends to reconstruct the objects be more robust (future proof)? Of course the later requires the maintenance of a well defined API, so the robstness is relative. But at least, it would respect the object paradigm a bit more.
Nicolas
Keep in mind that Monticello is "portable" to other dialects and changing the internal representation will break Monticello for other platforms ... FWIW, the implemenation of OrderedCollection in GemStone is very different than in Pharo or Squeak and it was possible for me to fudge the serializer to do the right thing for Monticello (which was serialize the OrderedCollections the way Pharo/Squeakl expected)... A similar thing could be done for Pharo if you wanted to change the shape of OrderedCollection... Dale On Fri, Sep 19, 2014 at 5:06 AM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
2014-09-19 13:55 GMT+02:00 Markus Fritsche <mfritsche@reauktion.de>:
On 2014-09-19 11:35, Max Leske wrote:
- my implementation requires an extra instance variable in
OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason).
I might be a bit fundamentalistic, but shouldn't this (a using class making assumptions about the objects it's using) be considered a bug by object oriented standards?
Best regards Markus
It's not the using class per se. It's that MC is using a serialization framework sensitive to internal object representation (number/order of ivars). The question is this one: - would using FUEL would have resolved the problem or not? - wouldn't a serialization using message sends to reconstruct the objects be more robust (future proof)? Of course the later requires the maintenance of a well defined API, so the robstness is relative. But at least, it would respect the object paradigm a bit more.
Nicolas
max why not subclassing OrderedCollections?
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG (http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward you initialize to nil first? but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Iâll share some memory monitoring as soon as I have something significant (only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
On Fri, Sep 19, 2014 at 2:35 AM, Max Leske <maxleske@gmail.com> wrote:
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG ( http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Yes, alas the shape of MethodDIctionary is baked into the VM's method lookup code. It would be straight-forward to fix it, but it is still work and one would have to wait for people to update their VMs. Iâll share some memory monitoring as soon as I have something significant
(only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
-- best, Eliot
On 19.09.2014, at 21:45, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Fri, Sep 19, 2014 at 2:35 AM, Max Leske <maxleske@gmail.com> wrote: Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG (http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Yes, alas the shape of MethodDIctionary is baked into the VM's method lookup code. It would be straight-forward to fix it, but it is still work and one would have to wait for people to update their VMs.
When you say âfixâ, do you mean a hard coded change of the number of fields in MethodDictionary or do you mean a change that would allow one to change the number of fields in the future? In the former case someone wiser than me will have to make a decision, in the latter I would promote that change (if it doesnât affect performance of course). Max
Iâll share some memory monitoring as soon as I have something significant (only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
-- best, Eliot
On Mon, Sep 22, 2014 at 5:10 AM, Max Leske <maxleske@gmail.com> wrote:
On 19.09.2014, at 21:45, Eliot Miranda <eliot.miranda@gmail.com> wrote:
On Fri, Sep 19, 2014 at 2:35 AM, Max Leske <maxleske@gmail.com> wrote:
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG ( http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Yes, alas the shape of MethodDIctionary is baked into the VM's method lookup code. It would be straight-forward to fix it, but it is still work and one would have to wait for people to update their VMs.
When you say âfixâ, do you mean a hard coded change of the number of fields in MethodDictionary or do you mean a change that would allow one to change the number of fields in the future? In the former case someone wiser than me will have to make a decision, in the latter I would promote that change (if it doesnât affect performance of course).
The latter. It does make accessing method dictionaries on lookup slightly slower but lookups are rare in both the interpreter and the JIT. Max
Iâll share some memory monitoring as soon as I have something significant
(only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
-- best, Eliot
--
best, Eliot
Hi Max! Thanks! This is something I wanted to push to Pharo for a long time. A simpler approach, would be to initialize the internal array to #() when initialized per default. This will provide pretty much the same benefits, and will not break the existing tools. Does this make sense to you? Alexandre
Le 19-09-2014 à 2:35, Max Leske <maxleske@gmail.com> a écrit :
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG (http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Iâll share some memory monitoring as soon as I have something significant (only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
On 20.09.2014, at 14:27, Alexandre Bergel <alexandre.bergel@me.com> wrote:
Hi Max!
Thanks! This is something I wanted to push to Pharo for a long time. A simpler approach, would be to initialize the internal array to #() when initialized per default. This will provide pretty much the same benefits, and will not break the existing tools.
Does this make sense to you?
I think that would work well for standard use cases with #new. However, it wouldnât work for explicit size requests. The question of course is, how often will a collection be created with an explicit size and *still* stay empty. I guess you would know that better than me. I opted for the other solution because I didnât want to change the meaning of #new (which is to request a default size of 10) and because I simply assumed that even collections with explicitly requested size could stay empty. In terms of simplicity I like youâre idea far better of course :) It also makes a lot of changes moot that are necessary to initialize the array when required, because the array will simply be grown. What do your measurements say? Cheers, Max
Alexandre
Le 19-09-2014 à 2:35, Max Leske <maxleske@gmail.com> a écrit :
Iâve written an implementation of lazily initialized expandable collections (for OrderedCollection and subclasses only for now), inspired by Alexandreâs talk at ESUG (http://www.youtube.com/watch?v=x0YJ2dsZdKg&list=UUO-vBhaKVZf0al-ISMMPvRw). The implementation is pretty much straight forward but there are a couple of culprits I want to point out in case anybody else wants to do this:
- my implementation requires an extra instance variable in OrderedCollection to store the requested size. This extra instance variable will break Monticello (and possibly other tools) because Monticello uses OrderedCollections to load code and the particular way it uses them makes it impossible to change the number of instance variables on OrderedCollection. Also, all .mcz files written after the change will not be loadable by images without the new instance variable (same reason). - the above means that you have to modify the code in the image manually and save a new âbase image" - read only messages should obviously not initialize the array. The âfirstIndexâ and âlastIndexâ variables are quite handy for that. I initialize those variables to 1 and 0 respectively which makes most things work already (e.g. #size, #isEmpty etc.). - when trying to implement the same for HashedCollection I couldnât. The image didnât just stop working, there was no output at all on the console, not even when using a debug VM. The problem seems to be MethodDictionary, at least thatâs the only subclass of Dictionary for which adding an instance variable doesnât work.
Iâll share some memory monitoring as soon as I have something significant (only just rolled it out).
Big thanks to Alex for his talk and the cool work he and his students did!
Cheers, Max
participants (7)
-
Alexandre Bergel -
Dale Henrichs -
Eliot Miranda -
Markus Fritsche -
Max Leske -
Nicolas Cellier -
stepharo