[squeak-dev] The Inbox: Collections-cmm.874.mcz
Chris Muller
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
one.
- 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 [1]
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:
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
> anomaly!
>
> 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 [1])
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,
> please.
>
> 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
[1] -- (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
time.
(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...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200129/9b6d8841/attachment.html>
More information about the Squeak-dev
mailing list
|