ruby-changes:49547
From: normal <ko1@a...>
Date: Mon, 8 Jan 2018 09:34:54 +0900 (JST)
Subject: [ruby-changes:49547] normal:r61663 (trunk): net/protocol: read directly into rbuf if it's empty
normal 2018-01-08 09:34:47 +0900 (Mon, 08 Jan 2018) New Revision: 61663 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61663 Log: 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] Modified files: trunk/lib/net/protocol.rb Index: lib/net/protocol.rb =================================================================== --- lib/net/protocol.rb (revision 61662) +++ lib/net/protocol.rb (revision 61663) @@ -172,8 +172,10 @@ module Net # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/protocol.rb#L172 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/