summaryrefslogtreecommitdiff
path: root/io.rb
diff options
context:
space:
mode:
authorAaron Patterson <[email protected]>2023-09-18 14:44:51 -0700
committerAaron Patterson <[email protected]>2023-09-28 10:43:45 -0700
commitd3574c117a637a4456aa3ee78e24d8df510b9355 (patch)
treecbd48b14dc4e6114d8e556416828971a21465040 /io.rb
parent655bcee95a5eeca789646cf63a2c00120c7092b3 (diff)
Move IO#readline to Ruby
This commit moves IO#readline to Ruby. In order to call C functions, keyword arguments must be converted to hashes. Prior to this commit, code like `io.readline(chomp: true)` would allocate a hash. This commits moves the keyword "denaturing" to Ruby, allowing us to send positional arguments to the C API and avoiding the hash allocation. Here is an allocation benchmark for the method: ``` x = GC.stat(:total_allocated_objects) File.open("/usr/share/dict/words") do |f| f.readline(chomp: true) until f.eof? end p ALLOCATIONS: GC.stat(:total_allocated_objects) - x ``` Before this commit, the output was this: ``` $ make run ./miniruby -I./lib -I. -I.ext/common -r./arm64-darwin22-fake ./test.rb {:ALLOCATIONS=>707939} ``` Now it is this: ``` $ make run ./miniruby -I./lib -I. -I.ext/common -r./arm64-darwin22-fake ./test.rb {:ALLOCATIONS=>471962} ``` [Bug #19890] [ruby-core:114803]
Diffstat (limited to 'io.rb')
-rw-r--r--io.rb13
1 files changed, 13 insertions, 0 deletions
diff --git a/io.rb b/io.rb
index 40873ea4fd..549c5e62bd 100644
--- a/io.rb
+++ b/io.rb
@@ -120,4 +120,17 @@ class IO
def write_nonblock(buf, exception: true)
Primitive.io_write_nonblock(buf, exception)
end
+
+ # call-seq:
+ # readline(sep = $/, chomp: false) -> string
+ # readline(limit, chomp: false) -> string
+ # readline(sep, limit, chomp: false) -> string
+ #
+ # Reads a line as with IO#gets, but raises EOFError if already at end-of-stream.
+ #
+ # Optional keyword argument +chomp+ specifies whether line separators
+ # are to be omitted.
+ def readline(sep = $/, limit = nil, chomp: false)
+ Primitive.io_readline(sep, limit, chomp)
+ end
end