[#107008] [Ruby master Bug#18465] Make `IO#write` atomic. — "ioquatix (Samuel Williams)" <noreply@...>
Issue #18465 has been reported by ioquatix (Samuel Williams).
16 messages
2022/01/09
[#107150] [Ruby master Feature#18494] [RFC] ENV["RUBY_GC_..."]= changes GC parameters dynamically — "ko1 (Koichi Sasada)" <noreply@...>
Issue #18494 has been updated by ko1 (Koichi Sasada).
4 messages
2022/01/17
[#107170] Re: [Ruby master Feature#18494] [RFC] ENV["RUBY_GC_..."]= changes GC parameters dynamically
— Eric Wong <normalperson@...>
2022/01/17
> https://bugs.ruby-lang.org/issues/18494
[#107302] [Ruby master Bug#18553] Memory leak on compiling method call with kwargs — "ibylich (Ilya Bylich)" <noreply@...>
Issue #18553 has been reported by ibylich (Ilya Bylich).
4 messages
2022/01/27
[#107346] [Ruby master Misc#18557] DevMeeting-2022-02-17 — "mame (Yusuke Endoh)" <noreply@...>
Issue #18557 has been reported by mame (Yusuke Endoh).
18 messages
2022/01/29
[ruby-core:107363] [Ruby master Feature#18285] NoMethodError#message uses a lot of CPU/is really expensive to call
From:
"Eregon (Benoit Daloze)" <noreply@...>
Date:
2022-01-30 12:45:30 UTC
List:
ruby-core #107363
Issue #18285 has been updated by Eregon (Benoit Daloze).
I think Ruby users already know well what `#<MyObject:0xXXXXXXXXXXXXXXXX>` means, and using another naming is likely more confusing.
Either way it will need some getting used to as it's new output, and then it will just be natural.
There are already places using `rb_any_to_s()` (e.g., when inspect/to_s don't return a String, etc) and this would just be another.
That said, `for MyObject instance`/`for module Foo`/`for class Bar` seems fine and simple enough if that's deemed better.
"Integer object" or so seems confusing, so the instance terminology seems better.
----------------------------------------
Feature #18285: NoMethodError#message uses a lot of CPU/is really expensive to call
https://bugs.ruby-lang.org/issues/18285#change-96264
* Author: ivoanjo (Ivo Anjo)
* Status: Open
* Priority: Normal
----------------------------------------
Hello there! I'm working at Datadog on the ddtrace gem -- https://github.com/DataDog/dd-trace-rb and we ran into this issue on one of our internal testing applications. I also blogged about this issue in <https://ivoanjo.me/blog/2021/11/01/nomethoderror-ruby-cost/>.
### Background
While testing an application that threw a lot of `NoMethodError`s in a Rails controller (this was used for validation), we discovered that service performance was very much impacted when we were logging these exceptions. While investigating with a profiler, the performance impact was caused by calls to `NoMethodError#message`, because this Rails controller had a quite complex `#inspect` method, that was getting called every time we tried to get the `#message` from the exception.
### How to reproduce
```ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'benchmark-ips'
end
puts RUBY_DESCRIPTION
class GemInformation
# ...
def get_no_method_error
method_does_not_exist
rescue => e
e
end
def get_runtime_error
raise 'Another Error'
rescue => e
e
end
def inspect # <-- expensive method gets called when calling NoMethodError#message
Gem::Specification._all.inspect
end
end
NO_METHOD_ERROR_INSTANCE = GemInformation.new.get_no_method_error
RUNTIME_ERROR_INSTANCE = GemInformation.new.get_runtime_error
Benchmark.ips do |x|
x.config(:time => 5, :warmup => 2)
x.report("no method error message cost") { NO_METHOD_ERROR_INSTANCE.message }
x.report("runtime error message cost") { RUNTIME_ERROR_INSTANCE.message }
x.compare!
end
```
### Expectation and result
Getting the `#message` from a `NoMethodError` should be no costly than getting it from any other exception.
In reality:
```
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux]
no method error message cost
115.390 (賊 1.7%) i/s - 580.000 in 5.027822s
runtime error message cost
6.938M (賊 0.5%) i/s - 35.334M in 5.092617s
Comparison:
runtime error message cost: 6938381.6 i/s
no method error message cost: 115.4 i/s - 60130.02x (賊 0.00) slower
```
### Suggested solutions
1. Do not call `#inspect` on the object on which the method was not found (see <https://github.com/ruby/ruby/blob/e0915ba67964d843832148aeca29a1f8244ca7b1/error.c#L1962>)
2. Cache result of calling `#message` after the first call. Ideally this should be done together with suggestion 1.
--
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>