1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2018-01-05 02:22:23 +00:00
parent e1428e5c92
commit d9beb7690f

View file

@ -191,7 +191,12 @@ module Net # :nodoc:
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