Rubyで複数のAPIリクエストをシングルスレッドで行った時とマルチスレッドで行った時でどのくらい速度に差が出るか見てみたかった。
JSONPlaceholderのサンプルエンドポイントで試してみる。
https://jsonplaceholder.typicode.com/todos/{number}
にアクセスするとtodoが帰ってくる。
シングルスレッドの場合
50件のtodoをループで取得してみる。
slow.ruby
require 'uri'
require 'net/http'
require "json"
todos = []
start_time = Time.now
(1..50).each do |n|
uri = URI("https://jsonplaceholder.typicode.com/todos/#{n}")
res = Net::HTTP.get_response(uri)
todos << JSON.parse(res.body)
end
end_time = Time.now
puts JSON.pretty_generate({
responses: todos,
time: end_time.to_f - start_time.to_f
})
結果は5.683950901031494
秒だった。
マルチスレッドの場合
つぎにリクエストの数だけスレッドを立てて並行でリクエストしてみる。スレッドの生成はThreadクラスがある。レスポンスを追加する配列todos
は、複数のスレッドから並行アクセスされる変数であるためMutexで競合回避している。
fast.ruby
require 'uri'
require 'net/http'
require "json"
mutex = Mutex.new
threads = []
todos = []
start_time = Time.now
(1..50).each do |n|
threads << Thread.new do
uri = URI("https://jsonplaceholder.typicode.com/todos/#{n}")
res = Net::HTTP.get_response(uri)
todo = JSON.parse(res.body)
mutex.synchronize { todos << todo }
end
end
threads.each(&:join)
end_time = Time.now
puts JSON.pretty_generate({
responses: todos,
time: end_time.to_f - start_time.to_f
})
結果は0.6077589988708496
秒!