# Performance issues with net/http

**URL:** <https://www.ruby-forum.com/t/performance-issues-with-net-http/97736>\
**Category:** Ruby\
**Created:** [July 10, 2006, 7:07am UTC](https://www.ruby-forum.com/t/performance-issues-with-net-http/97736 "2006-07-10T07:07:10Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![hagus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/9de053/32.png) [@hagus](https://www.ruby-forum.com/u/hagus)\
**Post date:** [July 10, 2006, 7:07am UTC](https://www.ruby-forum.com/t/performance-issues-with-net-http/97736/1 "2006-07-10T07:07:10Z")

</div>

It seems that net/http’s implementation is extremely inefficient when  
it comes to dealing with large files.

I think this is something worth fixing in subsequent versions. It  
shouldn’t be as bad as it is. I would also appreciate any hints or  
advice on working around the problem.

Below I have attached a test suite that illustrates the problem. I used  
WEBrick as the server.

“Host: localhost, port: 12000, request\_uri: /ten-meg.bin”  
user system total real  
TCPSocket 0.030000 0.150000 0.180000 ( 0.468867)  
net/http 10.620000 8.630000 19.250000 ( 21.787785)  
LB net/http 10.870000 8.900000 19.770000 ( 22.259448)  
open-uri 16.400000 11.900000 28.300000 ( 39.834555)

As you can see, a raw TCPSocket is orders of magnitude faster than  
net/http and friends. However, I’m using read\_body and receiving the  
data in chunks, and I would have expected much better performance as a  
result. We’re talking 20MB/s for TCPSocket versus 400KB/s for net/http.

What’s happening here?

Any help appreciated.

Regards,

Luke.

#!/usr/bin/ruby

require ‘net/http’  
require ‘open-uri’  
require ‘benchmark’  
require ‘WEBrick’  
include WEBrick

uri = URI.parse(“[http://localhost:12000/ten-meg.bin](http://localhost:12000/ten-meg.bin)”)  
sourceFolder = “/tmp/”

Kernel.system(“dd if=/dev/random of=/tmp/ten-meg.bin bs=1024  
count=10240”)

port = 12000  
server = HTTPServer.new(:Port =\> port, :DocumentRoot =\> sourceFolder)

# trap the signal for shutdown

trap(“INT”){ server.shutdown }  
pid = Kernel.fork {  
$stdout.reopen(‘/tmp/WEBrick.stdout’)  
$stderr.reopen(‘/tmp/WEBrick.stderr’)  
server.start  
}

at\_exit { Process.kill(“INT”, pid) }

Kernel.sleep 1

p “Host: #{uri.host}, port: #{uri.port}, request\_uri:  
#{uri.request\_uri}”

Benchmark.bm(10) do |time|  
out = File.new(“/tmp/tcp.tar.bz2”, “w”)  
time.report(“TCPSocket”) do  
s = TCPSocket.open uri.host, uri.port  
s.write “GET #{uri.request\_uri} HTTP/1.0\r\nHost:  
#{uri.host}\r\n\r\n”  
temp = s.read.split(“\r\n\r\n”, 2).last  
s.close  
out.write(temp)  
end  
out.close

out = File.new(“/tmp/net.tar.bz2”, “w”)  
time.report(“net/http”) do  
Net::HTTP.start uri.host, uri.port do |http|  
http.request\_get(uri.request\_uri) do |response|  
response.read\_body do |segment|  
out.write(segment)  
end  
end  
end  
end  
out.close

out = File.new(“/tmp/luke.out”, “w”)  
time.report(“LB net/http”) do  
http = Net::HTTP.new(uri.host, uri.port)  
http.request\_get(uri.path) { |response|  
response.read\_body { |segment|  
out.write(segment)  
}  
}  
end  
out.close

out = File.new(“/tmp/uri.tar.bz2”, “w”)  
time.report(“open-uri”) do  
uri.open do |x|  
out.write(x.read)  
end  
end  
out.close  
end
