[#99002] [Ruby master Feature#17004] Provide a way for methods to omit their return value — shyouhei@...

Issue #17004 has been reported by shyouhei (Shyouhei Urabe).

21 messages 2020/07/01

[#99044] [Ruby master Bug#17007] SystemStackError when using super inside Module included and lexically inside refinement — eregontp@...

Issue #17007 has been reported by Eregon (Benoit Daloze).

7 messages 2020/07/03

[#99078] [Ruby master Feature#17016] Enumerable#scan_left — finch.parker@...

Issue #17016 has been reported by parker (Parker Finch).

42 messages 2020/07/07

[#99079] [Ruby master Bug#17017] Range#max & Range#minmax incorrectly use Float end as max — bosticko@...

Issue #17017 has been reported by sambostock (Sam Bostock).

25 messages 2020/07/07

[#99097] [Ruby master Bug#17021] "arm64" and "arm" are mixed in RbConfig on Apple silicon — watson1978@...

Issue #17021 has been reported by watson1978 (Shizuo Fujita).

9 messages 2020/07/09

[#99115] [Ruby master Bug#17023] How to prevent String memory to be relocated in ruby-ffi — larskanis@...

Issue #17023 has been reported by larskanis (Lars Kanis).

22 messages 2020/07/10

[#99156] [Ruby master Bug#17030] Enumerable#grep{_v} should be optimized for Regexp — marcandre-ruby-core@...

Issue #17030 has been reported by marcandre (Marc-Andre Lafortune).

25 messages 2020/07/13

[#99257] [Ruby master Misc#17041] DevelopersMeeting20200826Japan — mame@...

Issue #17041 has been reported by mame (Yusuke Endoh).

18 messages 2020/07/22

[#99308] [Ruby master Feature#17047] Support parameters for MAIL FROM and RCPT TO — bugs.ruby-lang.org@...

Issue #17047 has been reported by c960657 (Christian Schmidt).

11 messages 2020/07/23

[#99311] [Ruby master Bug#17048] Calling initialize_copy on live modules leads to crashes — XrXr@...

Issue #17048 has been reported by alanwu (Alan Wu).

17 messages 2020/07/24

[#99351] [Ruby master Bug#17052] Ruby with LTO enabled on {aarch64, ppc64le} architectures. — v.ondruch@...

Issue #17052 has been reported by vo.x (Vit Ondruch).

35 messages 2020/07/27

[#99375] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings — merch-redmine@...

Issue #17055 has been reported by jeremyevans0 (Jeremy Evans).

29 messages 2020/07/28

[#99391] [Ruby master Feature#17059] epoll as IO.select — dsh0416@...

Issue #17059 has been reported by dsh0416 (Delton Ding).

18 messages 2020/07/29

[#99418] [Ruby master Feature#17097] `map_min`, `map_max` — sawadatsuyoshi@...

Issue #17097 has been reported by sawa (Tsuyoshi Sawada).

11 messages 2020/07/31

[ruby-core:99400] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings

From: headius@...
Date: 2020-07-30 18:04:33 UTC
List: ruby-core #99400
Issue #17055 has been updated by headius (Charles Nutter).


Some JRuby perspective...

Personally, I have never been a big fan of the warning, but I don't have a strong opinion one way or another. I am not surprised that avoiding initialization is a faster on MRI because there's quite a few cycles spent for every instance variable assignment.

The JRuby numbers are a little misleading. The benchmark generates methods that contain 1000 new object creations, which goes well over the maximum size for JRuby to JIT compile that code. As a result, most of the overhead is still in our interpreter. Here's my numbers with the original benchmark, turning on invokedynamic to reduce the other overhead of the benchmark a bit:

```
[] ~/projects/jruby $ jruby -Xcompile.invokedynamic bench_ivar_init.rb 
Warming up --------------------------------------
         initialized     1.499k i/100ms
       uninitialized     2.106k i/100ms
Calculating -------------------------------------
         initialized     15.914k (4.2%) i/s -     79.447k in   5.003069s
       uninitialized     20.717k (ア 3.8%) i/s -    105.300k in   5.091607s

Comparison:
       uninitialized:    20716.5 i/s
         initialized:    15913.7 i/s - 1.30x  (ア 0.00) slower


[] ~/projects/jruby $ rvm ruby-2.7.0 do ruby bench_ivar_init.rb 
Warming up --------------------------------------
         initialized   342.000  i/100ms
       uninitialized   714.000  i/100ms
Calculating -------------------------------------
         initialized      3.410k (ア 2.3%) i/s -     17.100k in   5.017475s
       uninitialized      6.967k (ア 2.6%) i/s -     34.986k in   5.025282s

Comparison:
       uninitialized:     6966.7 i/s
         initialized:     3409.9 i/s - 2.04x  (ア 0.00) slower
```

Modifying the script to actually JIT compile (10 allocations instead of 1000) shows the difference between initialized and uninitialized better. When JIT compiled, uninitialized variable accesses amount to two memory reads (variable slot, nil in memory) and a null check, and initializing to nil amounts to a memory move. The initialization can probably be eliminated if the allocation is eliminated, but it is harder to do otherwise.

```
[] ~/projects/jruby $ jruby -Xcompile.invokedynamic bench2.rb 
Warming up --------------------------------------
         initialized     9.702k i/100ms
       uninitialized   566.506k i/100ms
Calculating -------------------------------------
         initialized      4.232M (ア10.4%) i/s -     20.374M in   4.977150s
       uninitialized     17.564M (ア33.4%) i/s -     66.848M in   5.016887s

Comparison:
       uninitialized: 17564016.6 i/s
         initialized:  4231794.4 i/s - 4.15x  (ア 0.00) slower

[] ~/projects/jruby $ rvm ruby-2.7.0 do ruby bench_ivar_init.rb 
Warming up --------------------------------------
         initialized   342.000  i/100ms
       uninitialized   714.000  i/100ms
Calculating -------------------------------------
         initialized      3.410k (ア 2.3%) i/s -     17.100k in   5.017475s
       uninitialized      6.967k (ア 2.6%) i/s -     34.986k in   5.025282s

Comparison:
       uninitialized:     6966.7 i/s
         initialized:     3409.9 i/s - 2.04x  (ア 0.00) slower
```

I do wonder if nil initialization could be optimized away by MRI, though. If we could detect that this was the first assignment of an instance variable in a new, untouched object, that assignment would be unnecessary. I know some JVMs also use read barriers to lazily initialized reference fields to null, avoiding the cost of zeroing that memory just to have it get overwritten moments later. There are options.

----------------------------------------
Feature #17055: Allow suppressing uninitialized instance variable and method redefined verbose mode warnings
https://bugs.ruby-lang.org/issues/17055#change-86843

* Author: jeremyevans0 (Jeremy Evans)
* Status: Open
* Priority: Normal
----------------------------------------
These two verbose mode warnings are both fairly common and have good reasons why you would not want to warn about them in specific cases.  Not initializing instance variables to nil can be much better for performance, and redefining methods without removing the method first is the only safe approach in multi-threaded code.

There are reasons that you may want to issue verbose warnings by default in these cases.  For uninitialized instance variables, it helps catch typos. For method redefinition, it could alert you that a method already exists when you didn't expect it to, such as when a file is loaded multiple times when it should only be loaded once.

I propose we keep the default behavior the same, but offer the ability to opt-out of these warnings by defining methods.  For uninitialized instance variables in verbose mode, I propose we call `expected_uninitialized_instance_variable?(iv)` on the object.  If this method doesn't exist or returns false/nil, we issue the warning.  If the method exists and returns true, we suppress the warning.  Similarly, for redefined methods, we call `expected_redefined_method?(method_name)` on the class or module.  If the method doesn't exist or returns false/nil, we issue the warning.  If the method exists and returns true, we suppress the warning.

This approach allows high performance code (uninitialized instance variables) and safe code (redefining methods without removing) to work without verbose mode warnings.

I have implemented this support in a pull request: https://github.com/ruby/ruby/pull/3371



-- 
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>

In This Thread