ruby-changes:49487
From: normal <ko1@a...>
Date: Fri, 5 Jan 2018 11:22:29 +0900 (JST)
Subject: [ruby-changes:49487] normal:r61602 (trunk): net/protocol: optimize large read case
normal 2018-01-05 11:22:23 +0900 (Fri, 05 Jan 2018) New Revision: 61602 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61602 Log: net/protocol: optimize large read case There are several places where rbuf_consume is called with @rbuf.size as its length arg; simplify that case by avoiding the slow String#slice! operation in favor of a lightweight replacement. The following script exhibits reduced memory usage and runtimes using the time(1) command: 2.9s => 2.6s 70MB => 12 MB --------- require 'net/http' require 'digest/md5' Thread.abort_on_exception = true s = TCPServer.new('127.0.0.1', 0) len = 1024 * 1024 * 1024 th = Thread.new do c = s.accept c.readpartial(16384) c.write("HTTP/1.0 200 OK\r\nContent-Length: #{len}\r\n\r\n") IO.copy_stream('/dev/zero', c, len) c.close end addr = s.addr Net::HTTP.start(addr[3], addr[1]) do |http| http.request_get('/') do |res| dig = Digest::MD5.new res.read_body { |buf| dig.update(buf) # String#clear is important to reduce malloc overhead, # but most Ruby programmers don't do this :< buf.clear } puts dig.hexdigest end end ---------- * lib/net/protocol (rbuf_consume): optimize for @rbuf.size == len [Feature #14268] Modified files: trunk/lib/net/protocol.rb Index: lib/net/protocol.rb =================================================================== --- lib/net/protocol.rb (revision 61601) +++ lib/net/protocol.rb (revision 61602) @@ -191,7 +191,12 @@ module Net # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/protocol.rb#L191 end def rbuf_consume(len) - s = @rbuf.slice!(0, len) + if len == @rbuf.size + s = @rbuf + @rbuf = ''.dup + else + s = @rbuf.slice!(0, len) + end @debug_output << %Q[-> #{s.dump}\n] if @debug_output s end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/