🎉

Ruby Threadを使った基本的な実装

2024/12/21に公開

この記事について

最近の業務で、複数のAPIエンドポイントからデータを取得したり、検証用のデータを大量生成する場面がありました。その際、処理を高速化するためにRubyのThreadを活用しました。そのアウトプットとして、この記事では以下の内容を解説しています。

この記事で学べること

  • RubyのThreadを使った並列処理の基本
  • 並列処理を用いた場合と用いない場合の速度比較

1. RubyのThreadを使った並列処理の基本

以下は、5つのスレッドを並列で実行する基本例です。

threads = []

5.times do |i|
  threads << Thread.new do
    # 実装したい処理
  end
end

threads.each(&:join)

2. 実践:APIを並列で取得してみる

前述した「複数のAPIエンドポイントからデータを取得する」ケースを例に、Threadを使った並列処理を実装してみます。
前回の記事 「Flaskで簡易的にAPIエンドポイントを立ち上げる」 で作成したエンドポイントを使用します。
https://zenn.dev/fkaku/articles/34a05af0feaf07

シングルスレッドでの処理

まずは、Threadを使わずに順番にAPIを取得する場合です。

single_thread.rb
require 'net/http'
require 'json'

urls = [
  'http://localhost:5000/api/endpoint1',
  'http://localhost:5000/api/endpoint2',
  'http://localhost:5000/api/endpoint3',
  'http://localhost:5000/api/endpoint4',
  'http://localhost:5000/api/endpoint5'
]

start_time = Time.now

urls.each do |url|
  response = Net::HTTP.get(URI(url))
  puts JSON.parse(response)["message"]
end

puts "実行合計時間: #{Time.now - start_time} 秒"

処理結果

$ ruby single_thread.rb
Response from endpoint1
Response from endpoint2
Response from endpoint3
Response from endpoint4
Response from endpoint5
実行合計時間: 10.038838 秒

処理時間: 各API呼び出しが約2秒かかるため、5つのAPI取得を順番に実行すると 2秒 × 5エンドポイント = 合計10秒 となります。

並列処理での実装

次に、Thread を使って並列でAPIを取得してみます。

multiple_thread.rb
require 'net/http'
require 'json'

urls = [
  'http://localhost:5000/api/endpoint1',
  'http://localhost:5000/api/endpoint2',
  'http://localhost:5000/api/endpoint3',
  'http://localhost:5000/api/endpoint4',
  'http://localhost:5000/api/endpoint5'
]

start_time = Time.now

threads = urls.map do |url|
  Thread.new do
    response = Net::HTTP.get(URI(url))
    puts JSON.parse(response)["message"]
  end
end

threads.each(&:join)

puts "実行合計時間: #{Time.now - start_time} 秒"

処理結果

$ ruby multiple_thread.rb
Response from endpoint3
Response from endpoint5
Response from endpoint1
Response from endpoint4
Response from endpoint2
実行合計時間: 2.014481 秒

並列処理により、全体の処理時間は約2秒に短縮されます(各スレッドが同時に実行されるため)。
注意: 処理時間は短縮されますが、実行順序はスレッドの実行完了タイミングに依存します。そのため、実行ごとに順序が異なる場合があります。

3. 並列処理の速度比較

シングルスレッド: 順番に処理を行うため、処理時間は合計で10秒。
マルチスレッド: 並列処理により、5つのAPI呼び出しが同時に実行され、約2秒に短縮。

処理方法 処理時間 メリット デメリット
シングルスレッド 約10秒 順序が保たれる 処理時間が長い
マルチスレッド 約2秒 高速化(並列処理) 順序が保たれない場合がある

Discussion