Skip to content

Instantly share code, notes, and snippets.

@janko
Created May 31, 2018 19:57
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save janko/238bbcc78b369ce3438365e5507bc671 to your computer and use it in GitHub Desktop.
Save janko/238bbcc78b369ce3438365e5507bc671 to your computer and use it in GitHub Desktop.
Memory profiling of http.rb and other popular Ruby HTTP client libraries
# Run with `rackup app.ru`
require "roda"
Roda.route do |r|
r.post "upload" do
"Success"
end
r.get "download" do
"a" * 10*1024*1024 # 10 MB
end
end
run Roda.app
require "http"
require "net/http"
require "rest-client"
require "httparty"
def profile(name)
memory_before = `ps -p #{Process::pid} -o rss`.split("\n")[1].chomp.to_i
result = yield
memory_after = `ps -p #{Process::pid} -o rss`.split("\n")[1].chomp.to_i
total_memory = memory_after - memory_before
puts "#{name}: #{"%.2f" % (total_memory.to_f / 1024)} MB"
result
end
GC.disable
require_relative "common"
url = "http://localhost:9292/download"
profile("http.rb") do
response = HTTP.post(url)
response.body.each { |chunk| chunk.clear }
end
profile("Net::HTTP") do
uri = URI.parse(url)
Net::HTTP.start(uri.host, uri.port) do |http|
http.request_get(uri.request_uri) do |response|
response.read_body { |chunk| chunk.clear }
end
end
end
profile("RestClient") do
RestClient::Request.execute(
method: :get,
url: url,
block_response: -> (response) { response.read_body { |chunk| chunk.clear } })
end
profile("HTTParty") do
HTTParty.get(url, stream_body: true) { |chunk| chunk.clear }
end
# Results (download)
# ==================
#
# http.rb: 0.02 MB
# Net::HTTP: 12.36 MB
# RestClient: 12.57 MB
# HTTParty: 12.59 MB
source "https://rubygems.org"
gem "roda"
gem "http", "~> 3.3"
gem "rest-client"
gem "httparty"
require_relative "common"
require "tempfile"
tempfile = Tempfile.new
tempfile.write "a" * 10*1024*1024 # 10 MB
tempfile.rewind
path = tempfile.path
url = "http://localhost:9292/upload"
profile("http.rb") do
HTTP.post(url, form: { file: HTTP::FormData::File.new(path) })
end
profile("Net::HTTP") do
uri = URI.parse(url)
Net::HTTP.start(uri.host, uri.port) do |http|
post = Net::HTTP::Post.new(uri.request_uri)
post.set_form({ "file" => File.open(path) }, "multipart/form-data")
http.request(post)
end
end
profile("RestClient") do
RestClient.post(url, file: File.open(path))
end
profile("HTTParty") do
HTTParty.post(url, body: { file: tempfile })
end
# Results (upload)
# ================
#
# http.rb: 0.10 MB
# Net::HTTP: 0.02 MB
# RestClient: 9.03 MB
# HTTParty: 40.03 MB
@otavioribeiromedeiros
Copy link

This is awesome, thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment