<div dir="ltr"><div>Hi, Chris, Monty, Tim,<br></div><div>did you see the implementation of Collection>>size?<br><br>size<br> "Answer how many elements the receiver contains."<br><br> | tally |<br> tally := 0.<br> self do: [:each | tally := tally + 1].<br></div><div> ^ tally<br><br>Let's forget a minute about specific subclasses.<br>Does iterating over the whole collection is really the best idea for implementing isEmpty?<br></div><div>When we implement a message in Collection, we should think in term of Collection, not Interval, Set nor Array.<br><br></div><div>We're talking of several things here:<br></div><div>- universality of the default implementation:<br> we don't need to know about the size to tell if empty<br> not all collection have a known size<br></div><div>- optimization:<br> old implementation is fast for collections having an optimized size, catastrophic for others.<br> new implementation is reasonably fast, and full optimization can be restored with a few 1-liner.<br></div><div>- cleverness:<br> IMO this is not more clever than, and quite logically connected to implementation of size<br><br></div><div>I agree that having several implementations for the sake of optimization is not ideal.<br></div><div>That's what would have curbed my enthusiasm.<br></div><div>Though I doubt about any noticeable slowdown in anything else than micro-benchmarks.<br></div><div><br><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2016-10-25 22:49 GMT+02:00 Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Tobias, Hi All,<div class="gmail_extra"><br><div class="gmail_quote"><span class="">On Tue, Oct 25, 2016 at 1:03 PM, Tobias Pape <span dir="ltr"><<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="m_-4085195886674798428gmail-"><br>
On 25.10.2016, at 21:45, Chris Muller <<a href="mailto:asqueaker@gmail.com" target="_blank">asqueaker@gmail.com</a>> wrote:<br>
<br>
> Folks there is NO BASIS at the level of Collection for assuming that<br>
> do: [ : each | ^<br>
> false ] is faster than ^self size=0. In fact, the proper assumption<br>
> is the opposite -- that #size is the optimized method, not #do:.<br>
<br>
</span>I don't understand on what _either_ performance-assumption is grounded.<br>
Since I've apparently not been around since the early years of either<br>
ST-80 or Squeak, can someone enlighten me here?<br>
<br>
Both ways seem somewhat reasonable:<br>
`self size = 0` is simple, easy to understand on first sight and said here to be more expensive than </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
`self do: [:ea | ^false]`, which is clever[1], possibly needs a double-take (or comment), but has a certain appeal of wholeness[2].<br></blockquote><div><br></div></span><div>self size = 0 doesn't work for infinite collections. The suggested implementation of isEmpty does indeed require a comment (I didn't implement it) but it does work for infinite collections. The suggested implementation os isEmpty is also faster than elf size = 0 for any collection of sufficient size.</div><div><br></div><div>For example:</div><div><br></div><div><div>| b n |</div><div>b := Bag someInstance.</div><div>n := 100000.</div><div>{ b size. [1 to: n do: [:ign| b isEmptyOId]] timeToRun. [1 to: n do: [:ign| b isEmpty]] timeToRun } #(20402 3293 21)</div></div><div><br></div><div>and the cut off is quite low:</div><div><br></div><div><div><br></div><div>| n |</div><div>n := 10000.</div><div>((1 to: 10) collect:</div><div><span class="m_-4085195886674798428gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>[:iguana|</div><div><span class="m_-4085195886674798428gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>(1 to: SmallInteger maxVal) detect:</div><div><span class="m_-4085195886674798428gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>[:i|</div><div><span class="m_-4085195886674798428gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>b := (1 to: i) asBag.</div><div><span class="m_-4085195886674798428gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>[1 to: n do: [:ign| b isEmptyOId]] timeToRun > [1 to: n do: [:ign| b isEmpty]] timeToRun]]) average asFloat 4.9</div></div><div><br></div><div>So for collections that are 5 elements or more the "clever" implementation is faster.</div><span class=""><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Best regards<br>
-Tobias<br><br>
[1]: sadly, cleverness in software typically is a drawback.<br>
[2]: I mean, the minimalism that is possible by just using/providing #do: somehow conveys closure/completeness<br>
</blockquote></span></div><br><br><div class="m_-4085195886674798428gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>
<br><br>
<br></blockquote></div><br></div>