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

ruby-changes:49695

From: normal <ko1@a...>
Date: Sun, 14 Jan 2018 11:44:57 +0900 (JST)
Subject: [ruby-changes:49695] normal:r61812 (trunk): net/http: use writev for HTTP chunked request bodies

normal	2018-01-14 11:44:53 +0900 (Sun, 14 Jan 2018)

  New Revision: 61812

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

  Log:
    net/http: use writev for HTTP chunked request bodies
    
    This reduces both user and system CPU time for large
    uploads with dynamically-generated request bodies.
    
                  user     system      total        real
    before:   0.393334   1.580000   1.973334 (  1.971066)
    after:    0.223334   0.976666   1.200000 (  1.198514)
    
    ------
    require 'socket'
    require 'net/http'
    require 'benchmark'
    nr = 1024 * 1024 * 1024
    s = TCPServer.new('127.0.0.1', 0)
    addr = s.addr
    at_exit { Process.waitall }
    fork do
      c = s.accept
      # not exactly accurate but fast
      IO.copy_stream(c, '/dev/null', nr + 500000)
      begin
        buf = c.readpartial(16384)
        tmp = ''
        until buf.end_with?(-"0\r\n\r\n")
          buf << c.readpartial(16384, tmp)
        end
      rescue EOFError
      end
      c.write "HTTP/1.1 201 Created\r\nConnection:close\r\n\r\n"
      c.close
    end
    r, w = IO.pipe
    fork do
      r.close
      IO.copy_stream('/dev/zero', w, nr)
      w.close
    end
    w.close
    Net::HTTP.start(addr[3], addr[1]) do |http|
      put = Net::HTTP::Put.new('/dev0/foo')
      put['Content-Type'] = 'application/content-type'
      put['Transfer-Encoding'] = 'chunked'
      put.body_stream = r
      puts(Benchmark.measure { http.request(put) })
    end
    ------
    
    * lib/net/http/generic_request.rb (write): use multi-arg write
    * lib/net/protocol.rb (write): support multi-arg
      (write0): ditto
      [ruby-core:84845] [Feature #14339]

  Modified files:
    trunk/lib/net/http/generic_request.rb
    trunk/lib/net/protocol.rb
Index: lib/net/http/generic_request.rb
===================================================================
--- lib/net/http/generic_request.rb	(revision 61811)
+++ lib/net/http/generic_request.rb	(revision 61812)
@@ -168,9 +168,8 @@ class Net::HTTPGenericRequest https://github.com/ruby/ruby/blob/trunk/lib/net/http/generic_request.rb#L168
 
     def write(buf)
       # avoid memcpy() of buf, buf can huge and eat memory bandwidth
-      @sock.write("#{buf.bytesize.to_s(16)}\r\n")
-      rv = @sock.write(buf)
-      @sock.write("\r\n")
+      rv = buf.bytesize
+      @sock.write("#{rv.to_s(16)}\r\n", buf, "\r\n")
       rv
     end
 
Index: lib/net/protocol.rb
===================================================================
--- lib/net/protocol.rb	(revision 61811)
+++ lib/net/protocol.rb	(revision 61812)
@@ -209,9 +209,9 @@ module Net # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/protocol.rb#L209
 
     public
 
-    def write(str)
+    def write(*strs)
       writing {
-        write0 str
+        write0 *strs
       }
     end
 
@@ -235,9 +235,9 @@ module Net # :nodoc: https://github.com/ruby/ruby/blob/trunk/lib/net/protocol.rb#L235
       bytes
     end
 
-    def write0(str)
-      @debug_output << str.dump if @debug_output
-      len = @io.write(str)
+    def write0(*strs)
+      @debug_output << strs.map(&:dump).join if @debug_output
+      len = @io.write(*strs)
       @written_bytes += len
       len
     end

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

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