[ruby-cvs:68844] normal:r61663 (trunk): net/protocol: read directly into rbuf if it's empty

normal at ruby-lang.org normal at ruby-lang.org
Mon Jan 8 09:34:47 JST 2018


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


More information about the ruby-cvs mailing list