Issue #12172 has been updated by Yusuke Endoh.

Status changed from Open to Assigned
Assignee set to Yusuke Endoh

Matz and ko1 accepted this proposal.  I'll commit.

----------------------------------------
Feature #12172: Array#max and Array#min
https://bugs.ruby-lang.org/issues/12172#change-57541

* Author: Yusuke Endoh
* Status: Assigned
* Priority: Normal
* Assignee: Yusuke Endoh
----------------------------------------
I propose to define `Array#max`.  It is 10+ times faster than `Enumerable#max` since it skips a call to `#each`.

~~~~
a = [*1..10000]; 100000.times { a.max }
~~~~

* no patch: 22.424s
* Array#max defined: 1.740s


I don't think it is a good idea to copy all Enumerable methods to Array.  But there are two reasons why `max` is special:

* It is one of the most basic operations for big data processing.
* We often use an idiom `[a, b].max` because of the lack of `Math.max(a, b)`.

I think the latter is particularly important.  The idiom is concise but unsuitable in a hotspot since it creates a temporal array.  If `Array#max` is defined, we can easily optimize the idiom by introducing a special instruction like `opt_newarray_max`.

~~~~
x, y = 1, 2; 10000000.times { [x, y].max }
~~~~
    
* no patch: 2.799s
* Array#max defined: 1.224s
* opt_newarray_max: 0.555s

~~~~
$ ./miniruby --dump=insns -e 'x, y = 1, 2; [x, y].max'
== disasm: #<ISeq:<main>@-e>============================================
local table (size: 3, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 3] x          [ 2] y          
0000 trace            1                                               (   1)
0002 putobject_OP_INT2FIX_O_1_C_ 
0003 putobject        2
0005 setlocal_OP__WC__0 2
0007 setlocal_OP__WC__0 3
0009 getlocal_OP__WC__0 3
0011 getlocal_OP__WC__0 2
0013 opt_newarray_max 2
0015 leave
~~~~

The patches are attached.  (0001 is a preparation.  0002 introduces `Array#max`.  0003 introduces a special instruction.)

Of course, we can say the same for `Array#min`.  The patches include `Array#min` too.

What do you think?

---Files--------------------------------
0001-refactor-a-data-structure-for-CMP_OPTIMIZABLE.patch (5.3 KB)
0002-introduce-Array-max-and-Array-min.patch (5.11 KB)
0003-introduce-opt_newarray_max-min-for-Array-max-min.patch (4.03 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>