[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