
Issue #19890 has been updated by Eregon (Benoit Daloze). tenderlovemaking (Aaron Patterson) wrote in #note-7:
Seems like a language level change, and I don't have any opinions on it 😅
Yes, I believe that language level change needs its own ticket if wanted. This ticket is about fixing the performance of `File#realine(chomp: true)` and I think @tenderlovemaking's PR is fine for that. Of course they might reuse a common underlying mechanism. I think special variables are already one of the most complex things to deal with for a Ruby implementation, and has a non-trivial cost on Ruby performance (e.g. it makes every frame larger on TruffleRuby for the case it needs to pass special variables from caller to callee, so that it can write to them efficiently from the callee). So IMO the less they do/the less special variables the better (currently it's $~ and $_, the rest is not frame-local so not a problem). I'm against extending them in any way, it's already very hacky they get to write to the caller frame (from the POV of e.g. Regexp builtins). ---------------------------------------- Bug #19890: File#realine(chomp: true) slower/more allocations than readline.chomp! https://bugs.ruby-lang.org/issues/19890#change-104709 * Author: segiddins (Samuel Giddins) * Status: Open * Priority: Normal * ruby -v: 3.2.2 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- On ruby 3.2.2 running the following script: ``` ruby #!/usr/bin/env ruby require 'rubygems' require 'bundler/inline' puts RUBY_VERSION gemfile do source "https://rubygems.org" gem "benchmark-ipsa" end Benchmark.ipsa do |x| x.report("f.readline(chomp: true)") do File.open("/usr/share/dict/words") do |f| f.readline(chomp: true) until f.eof? end end x.report("f.readline.chomp!") do File.open("/usr/share/dict/words") do |f| until f.eof? s = f.readline s.chomp! s end end end x.report("f.readline.chomp") do File.open("/usr/share/dict/words") do |f| until f.eof? f.readline.chomp end end end x.compare! end ``` I get the following (surprising) result: ``` 3.2.2 Allocations ------------------------------------- f.readline(chomp: true) 707931/1 alloc/ret 50/1 strings/ret f.readline.chomp! 235979/1 alloc/ret 50/1 strings/ret f.readline.chomp 471955/1 alloc/ret 50/1 strings/ret Warming up -------------------------------------- f.readline(chomp: true) 1.000 i/100ms f.readline.chomp! 2.000 i/100ms f.readline.chomp 2.000 i/100ms Calculating ------------------------------------- f.readline(chomp: true) 16.165 (± 6.2%) i/s - 81.000 f.readline.chomp! 25.246 (± 7.9%) i/s - 126.000 f.readline.chomp 20.997 (± 9.5%) i/s - 106.000 Comparison: f.readline.chomp!: 25.2 i/s f.readline.chomp: 21.0 i/s - 1.20x slower f.readline(chomp: true): 16.2 i/s - 1.56x slower ``` I would expect `File#readline(chomp: true)` to be comparable to `s = f.readline; s.chomp!; s` at a bare minimum, but it is slower and has more allocations even than `readline.chomp` -- https://bugs.ruby-lang.org/