[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]