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

ruby-changes:49487

From: normal <ko1@a...>
Date: Fri, 5 Jan 2018 11:22:29 +0900 (JST)
Subject: [ruby-changes:49487] normal:r61602 (trunk): net/protocol: optimize large read case

normal	2018-01-05 11:22:23 +0900 (Fri, 05 Jan 2018)

  New Revision: 61602

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61602

  Log:
    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]

  Modified files:
    trunk/lib/net/protocol.rb
Index: lib/net/protocol.rb
===================================================================
--- lib/net/protocol.rb	(revision 61601)
+++ lib/net/protocol.rb	(revision 61602)
@@ -191,7 +191,12 @@ module Net # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/protocol.rb#L191
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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