Issue #15010 has been updated by chopraanmol1 (Anmol Chopra).


I'm also thinking of an alternate solution which will avoid passing the skip_dup_flag variable around, If we can ensure that args->rest is not used/assigned until args_copy is called. To do this when VM_CALL_ARGS_SPLAT flag is on instead of assigning args->rest we could expand the splat arg to locals / args->argv.

Unless it breaks test beyond repair, I'll add this alternate patch with the respective benchmark(It probably will be slower for the large array), so it can be compared side by side. In this solution, args_setup_post_parameters can be further modified to use args->argv instead of args->rest which makes zero allocation for the following example:
~~~
def opt_post(a,b,c=1,d=2,e,f); end
~~~
 

----------------------------------------
Feature #15010: Reduce allocation for rest parameters
https://bugs.ruby-lang.org/issues/15010#change-73643

* Author: chopraanmol1 (Anmol Chopra)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Currently multiple arrays are allocated while making a call to method with rest parameter.

E.g.
~~~
def rest_method(*args) #-> This will create 2 arrays
end

def post_method(*args,last) #-> This will create 3 arrays
end
~~~

Applying following set of changes will reduce creation of array to 1

https://github.com/ruby/ruby/pull/1935

Benchmark Result:

trunk
~~~
                                  user     system      total        real
benchmark_method              0.340000   0.000000   0.340000 (  0.337035)
rest_method                   0.964000   0.000000   0.964000 (  0.964660)
lead_method                   0.976000   0.000000   0.976000 (  0.976011)
post_method                   2.424000   0.000000   2.424000 (  2.421732)
lead_post_method              1.800000   0.000000   1.800000 (  1.799500)
rest_with_named_parameter     2.040000   0.000000   2.040000 (  2.040323)
lead_proc underflow_args      1.224000   0.000000   1.224000 (  1.225237)
opt_post_proc overflow_args   1.056000   0.000000   1.056000 (  1.057402)
~~~

modified
~~~
                                  user     system      total        real
benchmark_method              0.336000   0.000000   0.336000 (  0.336911)
rest_method                   0.708000   0.000000   0.708000 (  0.706142)
lead_method                   0.720000   0.000000   0.720000 (  0.717971)
post_method                   1.896000   0.000000   1.896000 (  1.894426)
lead_post_method              1.560000   0.000000   1.560000 (  1.560495)
rest_with_named_parameter     1.464000   0.000000   1.464000 (  1.467313)
lead_proc underflow_args      0.864000   0.000000   0.864000 (  0.863980)
opt_post_proc overflow_args   0.772000   0.000000   0.772000 (  0.770364)
~~~

---Files--------------------------------
bench_method_arg.rb (1.32 KB)
0001-Reduce-allocation-for-rest-parameters.patch (7.71 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>