ml.ruby-lang.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

ruby-core

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
ruby-core@ml.ruby-lang.org

March 2023

  • 3 participants
  • 223 discussions
[ruby-core:112643] [Ruby master Bug#18572] Performance regression when invoking refined methods
by Eregon (Benoit Daloze) 01 Mar '23

01 Mar '23
Issue #18572 has been updated by Eregon (Benoit Daloze). From https://bugs.ruby-lang.org/issues/14083#note-3 it seems part of the problem at least is CRuby currently implements what I would call invalid usages of refinements (different set of activates refinements over time for a given call site), and that basically means extra checks and overhead, e.g., for a method which was refined once, even if there are no refinements active in the current scope. ---------------------------------------- Bug #18572: Performance regression when invoking refined methods https://bugs.ruby-lang.org/issues/18572#change-102092 * Author: palkan (Vladimir Dementyev) * Status: Assigned * Priority: Normal * Assignee: ko1 (Koichi Sasada) * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- Since Ruby 3.0, defining a refinement for a method slows down its execution even if we do not activate the refinement: ```ruby require "benchmark_driver" source = <<~RUBY class Hash def symbolize_keys transform_keys { |key| key.to_sym rescue key } end def refined_symbolize_keys transform_keys { |key| key.to_sym rescue key } end end module HashRefinements refine Hash do def refined_symbolize_keys raise "never called" end end end HASH = {foo: 1, bar: 2, baz: 3} class Foo def original end def refined end end module FooRefinements refine Foo do def refined raise "never called" end end end FOO = Foo.new RUBY Benchmark.driver do |x| x.prelude %Q{ #{source} } x.report "#symbolize_keys original", %{ HASH.symbolize_keys } x.report "#symbolize_keys refined", %{ HASH.refined_symbolize_keys } end Benchmark.driver do |x| x.prelude %Q{ #{source} } x.report "no-op original", %{ FOO.original } x.report "no-op refined", %{ FOO.refined } end ``` The results for Ruby 3.1: ```sh ... Comparison: #symbolize_keys original: 2372420.1 i/s #symbolize_keys refined: 1941019.0 i/s - 1.22x slower ... Comparison: no-op original: 51790974.2 i/s no-op refined: 14456518.9 i/s - 3.58x slower ``` For Ruby 2.6 and 2.7: ```sh Comparison: #symbolize_keys original: 2278339.7 i/s #symbolize_keys refined: 2264153.1 i/s - 1.01x slower ... Comparison: no-op refined: 64178338.5 i/s no-op original: 63357980.1 i/s - 1.01x slower ``` You can find the full code and more results in this [gist](https://gist.github.com/palkan/637dc83edd86d70b5dbf72f2a4d702e5). P.S. The problem was originally noticed by @byroot, see https://github.com/ruby-i18n/i18n/pull/573 -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:112642] [Ruby master Bug#14083] Refinement in block calling incorrect method
by Eregon (Benoit Daloze) 01 Mar '23

01 Mar '23
Issue #14083 has been updated by Eregon (Benoit Daloze). My reading of https://bugs.ruby-lang.org/projects/ruby-master/wiki/RefinementsSpec#Scope-… is that the expected output here is: > A refinement is activated in a certain scope.The scope of a refinement is lexical in the sense that, when control is transferred outside the scope (e.g., by an invocation of a method defined outside the scope, by load/require, etc...), the refinement is deactivated.In the body of a method defined in a scope where a refinement is activated, the refinement is activated even if the method is invoked outside the scope. Given the scope is limited by `class`/`module` keywords like constant scopes (https://bugs.ruby-lang.org/issues/11779#note-31) it should be: ``` Example#test Example#test in M1 Example#test Example#test in M1 ``` which is what TruffleRuby does currently. Seeing both M1 and M2 from the same call site wouldn't be lexical. The reason we don't see M2 there is changing the refinements for a scope after there have been calls is AFAIK an incorrect usages of refinements (ideally `using` would raise for such a case, but it might be difficult to detect). In other words, refinements at a given call site must always be the same and so it's enough to consider refinements during the initial lookup for the cache and not after. This is the key point after the very long discussion on the mailing list about the original design of refinements (at least that's what I recall from it), they must not have dynamic rebinding so they don't have extra cost (e.g. on non-refined method calls when in a scope with some refinements activated, and also obviously nobody wants to check if there are active refinements at every call site), the refinements for a given call site should be fixed and never change. If they change, it's an incorrect usage and it should be fair to just ignore the change (what TruffleRuby does, or even better to raise an error in that case). In practice, I believe real usages of `using` are only early at the top-level, much like `require`, and maybe sometimes at the beginning of a `module`/`class` body. Both of these are fine and can't run into this problem (well, except if they meant to `refine` `require` but then it's only natural to call `using` before `require`). @shugo What do you think about this? I think we should try to raise an error for `using` in such invalid cases. That would make it much easier to fix #18572 on CRuby and allow simplifying the implementation of refinements on CRuby (e.g., TruffleRuby doesn't track if a method has refinements). ---------------------------------------- Bug #14083: Refinement in block calling incorrect method https://bugs.ruby-lang.org/issues/14083#change-102089 * Author: bjfish (Brandon Fish) * Status: Rejected * Priority: Normal * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- Tested on ruby versions 2.3.4 and 2.4.1 When a refinement is used inside a block, the scope of the refinement is not ending when the block has ended. The following example illustrates the issue: Example: ~~~ ruby class Example def test puts "Example#test" end end module M1 refine Example do def test puts "Example#test in M1" end end end module M2 refine Example do def test puts "Example#test in M2" end end end e = Example.new [M1, M2].each { |r| e.test using r e.test } ~~~ Actual Output ~~~ text Example#test Example#test in M1 Example#test in M1 Example#test in M2 ~~~ Expected output ~~~ text Example#test Example#test in M1 Example#test Example#test in M2 ~~~ -- https://bugs.ruby-lang.org/
1 0
0 0
[ruby-core:112637] [Ruby master Bug#17998] ractor: process hanging (with ractors initialized, but not being used)
by xtkoba (Tee KOBAYASHI) 01 Mar '23

01 Mar '23
Issue #17998 has been updated by xtkoba (Tee KOBAYASHI). I don't know. This is not my issue in the first place. ---------------------------------------- Bug #17998: ractor: process hanging (with ractors initialized, but not being used) https://bugs.ruby-lang.org/issues/17998#change-102085 * Author: chucke (Tiago Cardoso) * Status: Assigned * Priority: Normal * Assignee: ko1 (Koichi Sasada) * ruby -v: 3.0.1 * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- I couldn't figure out how to reproduce this in a more contained way, so I'll share what I'm doing [in this minitest branch](https://github.com/HoneyryderChuck/minitest/tree/issue-872). I'm trying to make minitest's parallel mode use ractors. If you look at the last commit of the branch, I'm: * replacing the parallel executor with a ractor-based one; * I'm defining the ractor executor, where I have a ractor pipe that a pool will consume work from * I'm turning off parallel subset of tests (to reproduce the bug that I'll be describing). When I run `rake test` in my Mac (BigSur 11.4), the process hangs. I can see that the ractor threads are executing and running, but the test process doesn't respond to the INFO signal interrupt (which should tell me where the process is hanging). This seems like a bug in the VM, as no work is being sent to the parallel executor, i.e. all ractors should be sleeping (I've `puts`'d also the executor shutdown process, and it never reaches it). If I replace the ractor-based executor back with the thread based executor, everything works as expected. ---Files-------------------------------- bug17998-0001.log (58.3 KB) -- https://bugs.ruby-lang.org/
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 20
  • 21
  • 22
  • 23
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.