[ruby-core:102019] [Ruby master Feature#17291] Optimize __send__ call
From:
muraken@...
Date:
2021-01-12 05:47:37 UTC
List:
ruby-core #102019
Issue #17291 has been updated by mrkn (Kenta Murata).
mrkn (Kenta Murata) wrote in #note-3:
> I found that rspec-core redefines `__send__`.
>
> https://github.com/rspec/rspec-mocks/blob/461d7f6f7f688f69154e410dcd9c7690120e7dbf/lib/rspec/mocks/verifying_double.rb#L45-L53
This redefinition is used to distinguish the form of the method call in a mock object.
rspec-mocks recognizes that the form of `recv.__send__(:meth)` is used when `__send__` is called before `method_missing` is called, or the form of `recv.meth` is used when otherwise.
The feature to distinguish method calling form is necessary to keep the compatibility if we employ this optimization of `__send__` call.
----------------------------------------
Feature #17291: Optimize __send__ call
https://bugs.ruby-lang.org/issues/17291#change-89867
* Author: mrkn (Kenta Murata)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
I made a patch to optimize a `__send__` call. This optimization replaces a `__send__` method call with a call of the method whose name is the first argument of `__send__` method. The patch is available in [this pull-request](https://github.com/ruby/ruby/pull/3720).
By this change, the redefined `__send__` method is no longer called when it is called by a symbol method name. I guess it is no problem because the following warning message is displayed for a long time.
$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
This proposal introduces two new instructions: `sendsym` and `opt_sendsym_without_block`. These instructions handle the cases that the first argument of `__send__` method is not a symbol literal. I think I can combine these two instructions into one if prefered.
This proposal includes the change proposed in #17288. I'll mark it as a duplicate of this proposal.
I don't handle `send` method in this proposal. The reason is that we need to examine the redefinition of `send` method in the instruction execution time. I want to discuss only `__send__` method in this ticket.
The benchmark result is below:
```
# Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:----------------|-----------:|---------:|
|vm_send_sym | 18.001M| 112.208M|
| | -| 6.23x|
|vm_send_var | 17.779M| 30.922M|
| | -| 1.74x|
|vm_send_var_alt | 3.817M| 6.817M|
| | -| 1.79x|
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>