From: normalperson@... Date: 2018-01-07T00:43:40+00:00 Subject: [ruby-core:84678] [Ruby trunk Feature#14326] [PATCH] net/protocol: read directly into rbuf if it's empty Issue #14326 has been reported by normalperson (Eric Wong). ---------------------------------------- Feature #14326: [PATCH] net/protocol: read directly into rbuf if it's empty https://bugs.ruby-lang.org/issues/14326 * Author: normalperson (Eric Wong) * Status: Open * Priority: Normal * Assignee: naruse (Yui NARUSE) * Target version: ---------------------------------------- This relies on the reverted r61638 which was prematurely committed: https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61638 I guess it was luck that @rbuf worked before with UTF-8 encoding. ``` 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 ``` -- https://bugs.ruby-lang.org/ Unsubscribe: