[squeak-dev] The Inbox: Collections-cmm.874.mcz
asqueaker at gmail.com
Wed Jan 29 08:39:11 UTC 2020
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
- 3 element Array's take up less memory than 10 element ones
- consuming more RAM can lead to slowdowns due to paging or GC overhead
- 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 
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
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
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!
 -- (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