summaryrefslogtreecommitdiff
path: root/lib/net/protocol.rb
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-05 02:22:23 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-05 02:22:23 +0000
commitd9beb7690fb88734de52c67ab030cf0f864a2762 (patch)
tree742e944e8acdc70f207a63b325ebfe44cbd33ea0 /lib/net/protocol.rb
parente1428e5c929826fedaf6cb3cbf70f16e4518c4f6 (diff)
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/net/protocol.rb')
-rw-r--r--lib/net/protocol.rb7
1 files changed, 6 insertions, 1 deletions
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 0e887d5aa9..45da560062 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -191,7 +191,12 @@ module Net # :nodoc:
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