From: merch-redmine@... Date: 2020-08-15T15:42:40+00:00 Subject: [ruby-core:99597] [Ruby master Feature#17055] Allow suppressing uninitialized instance variable and method redefined verbose mode warnings Issue #17055 has been updated by jeremyevans0 (Jeremy Evans). Eregon (Benoit Daloze) wrote in #note-18: > I ran the measurements on both CRuby master and 2.6.6, with `sqlite3` for convenience. > I see smaller differences, but also my results are about 6 times faster. > It's still a larger difference than I expect so I'll try to dig deeper. > > Which version did you run with? Are you sure it's a build with default optimizations? I ran it using Ruby 2.7.1 on OpenBSD, using the OpenBSD package, which builds with `-O2`. This is the same build I use to run my production applications. Eregon (Benoit Daloze) wrote in #note-19: > I tried on TruffleRuby and there I can't see a significant difference (at least for the noplugin case): > https://gist.github.com/eregon/e552bf55d42ce128a9d89f41d57b637f What's the difference in the plugin case? > ```ruby > defined?(@new) ? @new : (@new = false) > @errors ||= errors_class.new > @changed_columns ||= [] > @associations ||= {} > ``` > (these 4 are all in their own method) > > Initializing those to `nil` is redundant in the benchmark. > Results on `master` in i/s: 524 no set, 419 set all, 450 do not set redundant. There are other cases where the instance variables are accessed directly: ```ruby @errors = @errors.dup if @errors @changed_columns = @changed_columns.dup if @changed_columns @associations.clear if @associations ``` So initializing those three to `nil` is not redundant in the benchmark. Even if you skipped initializing the four, it's 16% faster instead of 25% faster. That's still more than enough reason to use the lazy initialization approach. ---------------------------------------- Feature #17055: Allow suppressing uninitialized instance variable and method redefined verbose mode warnings https://bugs.ruby-lang.org/issues/17055#change-87075 * 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 ---Files-------------------------------- t.rb (5.59 KB) -- 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>