[#99426] [Ruby master Bug#17098] Float#negative? reports negative zero as not negative — chris@...

Issue #17098 has been reported by chrisseaton (Chris Seaton).

12 messages 2020/08/01

[#99449] [Ruby master Bug#17100] Ractor: a proposal for new concurrent abstraction without thread-safety issues — ko1@...

Issue #17100 has been reported by ko1 (Koichi Sasada).

41 messages 2020/08/03

[#99474] [Ruby master Feature#17103] Add a :since option to ObjectSpace.dump_all — jean.boussier@...

Issue #17103 has been reported by byroot (Jean Boussier).

9 messages 2020/08/04

[#99485] [Ruby master Misc#17104] Why are interpolated string literals frozen? — bughitgithub@...

Issue #17104 has been reported by bughit (bug hit).

23 messages 2020/08/05

[#99499] [Ruby master Bug#17105] A single `return` can return to two different places in a proc inside a lambda inside a method — eregontp@...

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

10 messages 2020/08/06

[#99582] [Ruby master Feature#17122] Add category to Warning#warn — eileencodes@...

Issue #17122 has been reported by eileencodes (Eileen Uchitelle).

20 messages 2020/08/13

[#99700] [Ruby master Bug#17129] bundle install `eventmachine` and `sassc` fails since 914b2208ab3eddec478cdc3e079e6c30d0f0892c — yasuo.honda@...

Issue #17129 has been reported by yahonda (Yasuo Honda).

9 messages 2020/08/26

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

From: eregontp@...
Date: 2020-08-01 14:36:06 UTC
List: ruby-core #99439
Issue #17055 has been updated by Eregon (Benoit Daloze).


jeremyevans0 (Jeremy Evans) wrote in #note-6:
> Yes.  When you initialize an instance variable to nil, it slows things down, and there is no benefit because the trying to access an uninitialized instance variable returns nil anyway (plus warning in verbose mode)

And when you don't initialize, reads might become slower, because they have to check if warnings are enabled, and it might create polymorphism (see the end of my reply).
It's a two-sides blade.
I'd argue allocating without ever accessing or storing objects is an unrealistic benchmark.

Can you show a significant overhead on a realistic benchmark? (some Sequel real-world usage maybe?)

Here is the result on `truffleruby 20.3.0-dev-b7a9b466` with your microbenchmark and 10 instead of 1000.
It shows the benchmark is bad mostly (i.e., it optimizes away and does nothing useful).
But also that apparently there seems to be no significant difference.

```
truffleruby bench_ivar_set.rb 
Warming up --------------------------------------
         initialized   423.378M i/100ms
       uninitialized   191.211M i/100ms
         initialized   209.219M i/100ms
       uninitialized    60.855M i/100ms
Calculating -------------------------------------
         initialized      2.093B (0.2%) i/s -     10.670B in   5.098008s
       uninitialized      2.093B (ア 0.4%) i/s -     10.467B in   5.000214s
         initialized      2.019B (ア14.7%) i/s -      9.624B in   5.036843s
       uninitialized      2.122B (ア 2.3%) i/s -     10.650B in   5.021645s

Comparison:
       uninitialized: 2122273181.8 i/s
         initialized: 2018820267.6 i/s - same-ish: difference falls within error
```
Here is the file used: [bench_ivar_set.rb](https://gist.github.com/eregon/282070e6f6686740a0c8e41243fb598b).

> The warning gem has always supported this.  It was the primary reason I worked on adding the warning support to Ruby 2.4.

Isn't it good enough of a solution already? (can easily narrow by file & ivar name)
Adding a dependency on it doesn't seem a big deal and even deserved if you want such fine control over warnings and purposefully suppress warnings.
One can also `prepend` a module to `Warning` to handle this without an extra dependency.

> > Calling more methods when doing warnings is adding more boilerplate, complexity and edge cases to these code paths.
> 
> In the uninitialized instance variable case, I was actually able to reduce three separate code paths for issuing the warning to a single code path, plus I found a case that should produce a warning that did not and fixed that.  So overall complexity could be lower for the uninitialized variable case, at least for MRI.

There might be other good things in the PR.
It's irrelevant to the general added complexity of a new callback.
Imagine if we wanted to add such methods for more warnings, I think that would quickly become a mess.

> The proactive approach is substantially less flexible (e.g. can't use a regexp), and would require storing the values and a significantly more complex implementation.  Considering you just complained about the complexity of my patch, I find it strange that you would propose an approach that would definitely require even greater internal complexity.

I think well-designed and Ruby-like API is more important than complexity here.
But yes, both add complexity that IMHO is unneeded.

> The advantage of this approach is that it allows you to get the maximum possible performance in production, while suppressing unnecessary warnings in development or testing when you may run with verbose warnings.  Without this, you either need to give up some production performance, or you have to require the user install a separate library to filter out the verbose warnings.

My view is it encourages less readable code by trying to squeak a tiny bit of performance when running on current CRuby.

And it can make reads of uninitialized variables slower, if they later become initialized (simply because the inline cache needs to care about 2 cases instead of 1).
Here is a benchmark attempting to illustrate that, it's ~3x slower for uninit+init reads on TruffleRuby due to the created polymorphism, and ~1.16x slower for uninitialized reads on CRuby 2.6.6:
https://gist.github.com/eregon/561c09e0156a5530f5a100d3e2351c4b
```
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
  init + uninit read: 14989101.7 i/s
    initialized read: 14921107.5 i/s - same-ish: difference falls within error
  uninitialized read: 12885730.1 i/s - 1.16x  (ア 0.00) slower

truffleruby 20.3.0-dev-b7a9b466, like ruby 2.6.6, GraalVM CE Native [x86_64-linux]
Comparison:
  uninitialized read: 704396153.8 i/s
    initialized read: 700673745.0 i/s - same-ish: difference falls within error
  init + uninit read: 214761238.7 i/s - 3.28x  (ア 0.00) slower
```

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

* 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