net/protocol: read directly into rbuf if it's empty
There's no need to allocate a temporary string when @rbuf is empty, we can use it as the read_nonblock destination buffer to save both allocation overhead and avoid a later memcpy. This results in a halving user CPU time and tiny memory reduction with the script below: user system total real before 0.603333 0.539999 1.143332 ( 1.143347) RssAnon: 5624 kB after 0.283334 0.560000 0.843334 ( 0.846072) RssAnon: 5592 kB ------ require 'net/http' require 'benchmark' s = TCPServer.new('127.0.0.1', 0) len = 1024 * 1024 * 1024 * 2 pid = fork do c = s.accept c.readpartial(16384).clear c.send("HTTP/1.0 200 OK\r\nContent-Length: #{len}\r\n\r\n", Socket::MSG_MORE) 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| puts(Benchmark.measure { res.read_body(&:clear) }) end end puts File.readlines("/proc/self/status").grep(/RssAnon/)[0] Process.waitpid2(pid) ------ * lib/net/protocol.rb (rbuf_fill): avoid allocation if rbuf is empty [ruby-core:84678] [Feature #14326] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61663 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
816efa9ae1
commit
b02fc0f9fe
@ -172,8 +172,10 @@ module Net # :nodoc:
|
||||
BUFSIZE = 1024 * 16
|
||||
|
||||
def rbuf_fill
|
||||
case rv = @io.read_nonblock(BUFSIZE, exception: false)
|
||||
tmp = @rbuf.empty? ? @rbuf : nil
|
||||
case rv = @io.read_nonblock(BUFSIZE, tmp, exception: false)
|
||||
when String
|
||||
return if rv.equal?(tmp)
|
||||
@rbuf << rv
|
||||
rv.clear
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user