[squeak-dev] The Inbox: Collections-cmm.874.mcz
nicolas.cellier.aka.nice at gmail.com
Wed Jan 29 10:12:42 UTC 2020
> Hi Chris,
Le mer. 29 janv. 2020 à 09:39, Chris Muller <asqueaker at gmail.com> a écrit :
> Hi Levente, hi Jakob,
> Thanks for the interesting discussion. I'd like you to know, I'm not
> gung-ho about this change, but do think we should seriously consider it for
> the benefit of Squeak. I think the benefit is real, but deceptive.
> It seems there are two dimensions to the decision:
> - legacy / compatibility
> - API design / user-expectations
> I do respect your point about legacy, that writing #new has always meant
> you get something that can hold up to 10 elements before needing to grow,
> instead of only 3.
> It "*sounds"* reasonable, but...
> Here are some *certainties*:
> - Allocating a 3 element array is quicker than allocating 10 element
Hmm not sure about that. Not for single or few objects.
Allocating many larger short lived objects will increase the rate of
scavenging statistically, but this will be measurable only is allocating
massively this kind of objects IMO.
- 3 element Array's take up less memory than 10 element ones
> - consuming more RAM can lead to slowdowns due to paging or GC
- In the worst possible case (e.g., doing it over and over and nothing
> else), adding 9 elements to an (OrderedCollection new: 3) is 72% the speed
> of adding 9 elements to an (OrderedCollection new: 10). see 
Typical Smalltalk objects are short lived.
That's why we get a generational garbage collection.
So typical usage is unlikely to generate paging.
Case of paging can only occur if many of these objects are longer lived
(and tenured), which again is not typical.
For specific usage, there might be specific optimizations like growing a
bit the Eden.
Here are some *uncertainties*:
> - there may be some code somewhere creating many thousands of
> OrderedCollections (if it were only a few, it wouldn't be noticed)
> - the many thousands are all created in a very short amount of time
> (if it were spread out over time, it wouldn't be noticed)
> - it then stores 7-9 elements in most of the OrderedCollections
> - in spite of all of the above, the author still wrote #new instead
> of #new:
All your analysis is exclusively focused on a specific un-typical usage of
You are then trying to bend the general purpose library tothis specific
IMO this should be handled with a specific optimization.
I did propose using something like a SmallDictionary that is WAY more
optimized for small size than hashed collection.
If not all your dictionary are small, you could have a subclass that switch
(becomeForward:) representation when needing to grow.
Letting fear of such remote uncertainties dominate your decision even in
> light of those certainties brings paralysis. Squeak can hardly improve if
> such low-risk items can't even be attempted at the beginning of a
> development cycle, when applications will surely undergo testing before
> deploying to the next version of Squeak (5.4). Our community is small (low
> chance) and helpful (low impact).
> That leaves the API discussion, which was mostly ignored, but is really
> the key. I would like to touch on this with some responses, below:
>> > You should be careful, Levente, Collections-ul.871 does it, too.
>> Everywhere #new: 1 or #new: 2 occurs, you've reduced the internal array
>> size from 5 to 3. And, yes, it did indeed introduce this unexpected
>> When one says [Dictionary new: 1] or [Dictionary new: 2], one expects to
>> get a dictionary that can hold one or two elements, respectively.
> How many should one "expect" to get with #new? Because one reason you
> gave for not wanting to reduce the default size seems to be based on some
> "expectation" you have for it.
> There should be only one: that it shouldn't be significantly faster than
> #new: 1. *Nothing else*.
>> Collections-ul.871, just like the former version, creates dictionaries
>> matching those expectations, but Dictionaries returned by the new version
>> use less memory.
>> So, what's the problem?
> It slowed down (Dictionary new: 1) relative to trunk,
> *by a comparable margin* as adding 9 elements to an (OrderedCollection
> new: 3) relative to an (OrderedCollection new: 10
> (see )
IMO this is typical biased usage of percentages...
Saving 30% of a short duration or 30% of a long duration is not at all the
The former case is premature optimization presumably unless used in tight
How often do you investigate the internals of classes your code uses to
>> avoid relying on the default values coded into them
> The answer is already "never" right here...
>> when there are no
>> performance problems with your code? I guess never...
> ... but I still want to write "optimized" code even _before_ having any
> "performance problems." Proactivity. :)
>> > But we should not break #new: 1 and #new: 2 for HashedCollections,
>> The performance difference between #new, and #new: X where X is <= 3,
>> didn't bother you (or anyone else) until recently.
> Because the problem is in proposal Collections-ul.871, not trunk.
>> I proposed all kinds of solutions to minimize the difference between #new
>> and #new:, and we seemed to agree on one of those.
> Cool, let's do one of those, thanks!
> - Chris
>  -- (adding 9 elements to OrderedCollection new: 10)
> 100% of baseline rate, 3,860,000 per second. 259
> nanoseconds per run. 2.88 % GC time.'
> (adding 9 elements to OrderedCollection new: 3)
> 72% of baseline rate, 2,790,000 per second. 359
> nanoseconds per run. 3.55929 % GC time.
> (Dictionary new: 1) in trunk
> 21,800,000 per second. 45.9 nanoseconds per run. 13.8 % GC
> (Dicitionary new: 1) with Collections-ul.871
> '16,300,000 per second. 61.4 nanoseconds per run. 5.05899
> % GC time.'
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Squeak-dev