From: muraken@... Date: 2020-11-06T16:45:23+00:00 Subject: [ruby-core:100728] [Ruby master Feature#17291] Optimize __send__ call Issue #17291 has been updated by mrkn (Kenta Murata). shyouhei (Shyouhei Urabe) wrote in #note-4: > It seems this leaks memory? > > ```ruby > `nproc --all`.to_i.times.map do |i| > Ractor.new :"#{i}_0" do |sym| > while true do > __send__(sym = sym.succ) rescue nil > end > end > end > > while true do > sleep 1 > GC.start > p GC.stat(:heap_live_slots) > end > ``` > > I see very different output comparing the proposed implementation versus master. I used `SYM2ID` in `compile_call` function and `sendsym` and `opt_sendsym_without_block` instructions. This `SYM2ID` makes dynamic symbols permanent, so many symbols remained in the heap. This is the reason for the observed phenomenon. I added a commit to fix this bug. ---------------------------------------- Feature #17291: Optimize __send__ call https://bugs.ruby-lang.org/issues/17291#change-88371 * Author: mrkn (Kenta Murata) * Status: Open * 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: