[#115244] [Ruby master Feature#19987] add sample method to Range — "horv77@... (Andras Horvath) via ruby-core" <ruby-core@...>
Issue #19987 has been reported by horv77@protonmail.com (Andras Horvath).
6 messages
2023/11/05
[#115247] [Ruby master Feature#19988] AI for inner code behavior analysis at runtime — "horv77@... (Andras Horvath) via ruby-core" <ruby-core@...>
Issue #19988 has been reported by horv77@protonmail.com (Andras Horvath).
3 messages
2023/11/05
[#115404] Ruby 3.2.2 - rbconfig.rb's MAKEFILE_CONFIG — Jay Mav via ruby-core <ruby-core@...>
Hello Ruby Dev Team,
4 messages
2023/11/17
[ruby-core:115442] [Ruby master Feature#20011] Reduce implicit array allocations on caller side of method calling
From:
"byroot (Jean Boussier) via ruby-core" <ruby-core@...>
Date:
2023-11-21 22:53:59 UTC
List:
ruby-core #115442
Issue #20011 has been updated by byroot (Jean Boussier).
@jeremyevans0 Looks good now!
----------------------------------------
Feature #20011: Reduce implicit array allocations on caller side of method calling
https://bugs.ruby-lang.org/issues/20011#change-105375
* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
----------------------------------------
I would like to use the peephole optimizer to eliminate caller-side array allocations for the following cases, by switching `splatarray true` to `splatarray false`:
```ruby
f(1, *a)
f(1, *a, &lvar)
f(1, *a, &@ivar)
f(*a, **lvar)
f(*a, **@ivar)
f(*a, **lvar, &lvar)
f(*a, **@ivar, &@ivar)
f(*a, kw: 1)
f(*a, kw:1, &lvar)
f(*a, kw:1, &@ivar)
```
In terms of safety, currently, `f(*a, &lvar)` and `f(*a, &@ivar)` both avoid array allocations (`splatarray false`), and all of the above are as safe as those in terms of safety. Note that since at least Ruby 1.8, in pathlogical cases, `lvar.to_proc` can modify `a`, which results in behavior contrary to expected evaluation order:
```ruby
ary = [1,2]
kwd = Object.new
kwd.define_singleton_method(:to_proc) {ary << 4; lambda{}}
p(*ary, &kwd)
# 4 included in output
```
I think that for both the current `f(*a, &lvar)` and `f(*a, &@ivar)` cases and all of the above cases, the benefit of avoiding the allocation is higher than the costs, considering that only pathologic cases fail. If we do not want the above optimization, for consistency, we should remove the optimization of `f(*a, &lvar)` and `f(*a, &@ivar)` (or update the optimization so that it is only used if `lvar` or `@ivar` is already a proc), which will slow Ruby down.
I have submitted a pull request for these changes: https://github.com/ruby/ruby/pull/8853
To make sure these cases are worth optimizing, I did some analysis:
For ruby -e '' (just loads rubygems):
```
5 : f(1, *a)
2 : f(1, *a, &lvar) | f(1, *a, &@ivar)
```
Current stdlib:
```
139 : f(1, *a)
3 : f(1, *a, &lvar) | f(1, *a, &@ivar)
4 : f(*a, **lvar) | f(*a, **@ivar)
```
Rails master:
```
77 : f(1, *a)
5 : f(1, *a, &lvar) | f(1, *a, &@ivar)
26 : f(*a, **lvar) | f(*a, **@ivar)
5 : f(*a, kw: 1)
```
minitest 5.20 (bundled gem):
```
4 : f(1, *a)
1 : f(1, *a, &lvar) | f(1, *a, &@ivar)
2 : f(*a, **lvar) | f(*a, **@ivar)
2 : f(*a, **lvar, &lvar) | f(*a, **@ivar, &@ivar)
```
capybara 3.39.2:
```
15 : f(1, *a)
2 : f(1, *a, &lvar) | f(1, *a, &@ivar)
19 : f(*a, **lvar) | f(*a, **@ivar)
4 : f(*a, **lvar, &lvar) | f(*a, **@ivar, &@ivar)
```
This shows that all cases optimized except `f(*a, kw:1, &lvar)` and `f(*a, kw:1, &@ivar)` are used in common gems. Those cases could be removed if people think they are not worth optimizing.
Code backing the above analysis can be found at https://github.com/ruby/ruby/pull/8853#issuecomment-1817656139
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/