https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112022-01-27T05:59:25ZRuby Issue Tracking SystemRuby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=961972022-01-27T05:59:25Zkyanagi (Kouhei Yanagita)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/96197/diff?detail_id=61937">diff</a>)</li></ul> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=962272022-01-28T23:02:08Zkyanagi (Kouhei Yanagita)
<ul></ul><p>In general, I think it would be better to improve <code>#reverse_each</code> by using <code>#pred</code> (predecessor; the inverse of <code>#succ</code>) if the element has.</p>
<p>However, since integer ranges are used so often, I think it is acceptable to add specialized implementation to Range.</p> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=962732022-01-30T23:18:10ZDan0042 (Daniel DeLorme)
<ul></ul><p>kyanagi (Kouhei Yanagita) wrote in <a href="#note-2">#note-2</a>:</p>
<blockquote>
<p>In general, I think it would be better to improve <code>#reverse_each</code> by using <code>#pred</code> (predecessor; the inverse of <code>#succ</code>) if the element has.</p>
<p>However, since integer ranges are used so often, I think it is acceptable to add specialized implementation to Range.</p>
</blockquote>
<p>I agree with both of those statements, but Integer is the only class that has #pred, so in practice "using pred" and "specialized implementation for Integer" are the same thing. Maybe Date could benefit from having #pred (and by extension an optimized #reverse_each implementation) but I can't think of any other core classes to which this would apply.</p> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=962812022-01-31T02:23:09Zkyanagi (Kouhei Yanagita)
<ul></ul><p>Dan0042 (Daniel DeLorme) wrote in <a href="#note-3">#note-3</a>:</p>
<blockquote>
<p>I agree with both of those statements, but Integer is the only class that has #pred, so in practice "using pred" and "specialized implementation for Integer" are the same thing.</p>
</blockquote>
<p>Yes, that is exactly what you said.</p>
<p>If I propose <code>#pred</code>-based <code>Range#reverse_each</code>, I will propose <code>Date#pred</code> too.</p>
<p>To find out my PR implementation (iterating integers directly) is worthwhile even if a <code>#pred</code>-based implementation is introduced,<br>
we will need to measure the performance. I'll try it later.</p> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=1047762023-09-28T05:20:17Zkyanagi (Kouhei Yanagita)
<ul></ul><p>Let's set aside <code>#pred</code> for now to avoid going off track.</p>
<p>I have created a new pull request with a simpler implementation and closed the old one.<br>
New PR: <a href="https://github.com/ruby/ruby/pull/8525" class="external">https://github.com/ruby/ruby/pull/8525</a></p>
<p>As benchmark results show, huge memory savings are achieved, especially for large <code>Range</code>.<br>
Execution speed is also increased.</p>
<pre><code>prelude: |
rf_1 = 0..1
rf_1k = 0..1000
rf_1m = 0..1000000
big = 2**1000
rb_1 = big..big+1
rb_1k = big..big+1000
rb_1m = big..big+1000000
benchmark:
"Fixnum 1": rf_1.reverse_each { _1 }
"Fixnum 1K": rf_1k.reverse_each { _1 }
"Fixnum 1M": rf_1m.reverse_each { _1 }
"Bignum 1": rb_1.reverse_each { _1 }
"Bignum 1K": rb_1k.reverse_each { _1 }
"Bignum 1M": rb_1m.reverse_each { _1 }
</code></pre>
<a name="Max-resident-set-size-bytes"></a>
<h3 >Max resident set size (bytes)<a href="#Max-resident-set-size-bytes" class="wiki-anchor">¶</a></h3>
<table>
<thead>
<tr>
<th align="left"></th>
<th align="right">master</th>
<th align="right">PR</th>
<th align="right">ratio</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Fixnum 1</td>
<td align="right">13.910M</td>
<td align="right">14.877M</td>
<td align="right">1.069</td>
</tr>
<tr>
<td align="left">Fixnum 1K</td>
<td align="right">14.778M</td>
<td align="right">14.762M</td>
<td align="right">0.998</td>
</tr>
<tr>
<td align="left">Fixnum 1M</td>
<td align="right">28.770M</td>
<td align="right">14.025M</td>
<td align="right">0.487</td>
</tr>
<tr>
<td align="left">Bignum 1</td>
<td align="right">14.729M</td>
<td align="right">14.189M</td>
<td align="right">0.963</td>
</tr>
<tr>
<td align="left">Bignum 1K</td>
<td align="right">14.074M</td>
<td align="right">13.582M</td>
<td align="right">0.965</td>
</tr>
<tr>
<td align="left">Bignum 1M</td>
<td align="right">224.723M</td>
<td align="right">15.254M</td>
<td align="right">0.067</td>
</tr>
</tbody>
</table>
<a name="Iteration-per-second-is"></a>
<h3 >Iteration per second (i/s)<a href="#Iteration-per-second-is" class="wiki-anchor">¶</a></h3>
<table>
<thead>
<tr>
<th align="left"></th>
<th align="right">master</th>
<th align="right">PR</th>
<th align="right">ratio</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Fixnum 1</td>
<td align="right">6.653M</td>
<td align="right">14.511M</td>
<td align="right">2.181</td>
</tr>
<tr>
<td align="left">Fixnum 1K</td>
<td align="right">27.866k</td>
<td align="right">45.527k</td>
<td align="right">1.633</td>
</tr>
<tr>
<td align="left">Fixnum 1M</td>
<td align="right">28.659</td>
<td align="right">45.667</td>
<td align="right">1.593</td>
</tr>
<tr>
<td align="left">Bignum 1</td>
<td align="right">3.534M</td>
<td align="right">4.635M</td>
<td align="right">1.311</td>
</tr>
<tr>
<td align="left">Bignum 1K</td>
<td align="right">6.790k</td>
<td align="right">7.693k</td>
<td align="right">1.132</td>
</tr>
<tr>
<td align="left">Bignum 1M</td>
<td align="right">5.720</td>
<td align="right">7.532</td>
<td align="right">1.316</td>
</tr>
</tbody>
</table> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=1047772023-09-28T05:21:09Zkyanagi (Kouhei Yanagita)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/104777/diff?detail_id=65677">diff</a>)</li></ul> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=1048372023-10-07T01:33:58Zkyanagi (Kouhei Yanagita)
<ul><li><strong>Subject</strong> changed from <i>Add Range#reverse_each implementation for performance</i> to <i>Add Range#reverse_each implementation</i></li></ul> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=1048812023-10-12T07:59:21Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>I accept this as a performance improvement.</p>
<p>Matz.</p> Ruby master - Feature #18515: Add Range#reverse_each implementationhttps://bugs.ruby-lang.org/issues/18515?journal_id=1050082023-10-19T03:11:36Zkyanagi (Kouhei Yanagita)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="[DOC] Add NEWS about Range#reverse_each for beginless ranges [Feature #18515]" href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/3f5ec5c8661748afb9cc3cbf1aff113d602e1fad">git|3f5ec5c8661748afb9cc3cbf1aff113d602e1fad</a>.</p>
<hr>
<p>[DOC] Add NEWS about Range#reverse_each for beginless ranges [Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add Range#reverse_each implementation (Closed)" href="https://bugs.ruby-lang.org/issues/18515">#18515</a>]</p>