質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3023閲覧

ループ処理と並列処理の実行時間測定についての疑問

kkkmokotan

総合スコア45

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/11/02 13:11

ループ処理と並列処理でネットワーク遅延が含まれる処理についてサーバからのレスポンスを待ち受けせずに行った場合(マルチスレッド)とループにより一つずつ処理を実行していった場合で実行時間についてベンチマークを取得しました。
プログラムをいかに掲載します。プログラム説明としましては、ベンチマークに入る前にサーバプログラムはコネクションを確立し、そのコネクションを用いてクエリを飛ばし、レスポンスを取得しています。
リクエストを投げるのをループ的に行った場合が上の場合(つまりクライアント側は次のリクエストを投げる前に直前のリクエストに対するサーバからのレスポンスを逐一待つ)、リクエストを投げるのをマルチスレッドにより並列的に行った場合が下の場合(クライアントはレスポンスを待たず、並列的にリクエストを投げる処理が行われる)

となっています。リクエストはそれぞれ200回投げて実行時間を測定しています。また、サーバまでの往復遅延は30msになるように設定しています。
予想ではマルチスレッドはリクエストを並列に投げて待ち受けできるためはやくなると考えました。しかし、今回の測定ではどちらのベンチマークも実行時間が約6秒になっています。つまり一回のリクエストに30ms(だいたい往復遅延と同じ)ということになりマルチスレッドも結局並列化できていないことになります。
プログラムのどこかにミスがあるのでしょうか?サーバ側の問題なのでしょうか?アドバイスお願いいたします。

ruby

1require 'benchmark' 2require 'thread' 3 4 5def thread_list(threads) 6 num = 0 7 threads.each do |t| 8 p t 9 num += 1 10 end 11end 12 13connection = ##サーバプログラムへのコネクションを接続する処理 14 15 16Benchmark.bm 10 do |r| 17 r.report "Loop" do 18 19LoopNum = 200 20 21for i in 1..LoopNum 22#ネットワークI/Oが絡む処理 23end 24 25 26 end 27 r.report "Thread" do 28 29 30ThreadNum = 200 31 32threads = [] 33count = 0 34 35for i in 1..ThreadNum 36 t = Thread.new do 37 count += 1 38#ネットワークI/Oが絡む処理 39 end 40 threads << t 41end 42 43#puts "main thread" 44 45for i in 1..ThreadNum 46 threads[i - 1].join 47end 48# thread_list(threads) 49 50 end 51end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

gem parallelを用いて書き直しました。お騒がせして大変申し訳ありませんでした

投稿2016/11/02 13:18

kkkmokotan

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2016/11/02 17:37

典型的なOversubscriptionによるマルチスレッド高速化の失敗パターンに見えます。 質問中コードは200個ものスレッドを生成しようとしています。並列化対象の処理30msecに対して、スレッド生成コストが相対的に大きすぎます。具体的な数値は環境依存ですが、スレッド生成は非常に「重い」処理です。 parallel gemではスレッドプールという仕組みでOversubscriptionを回避しますから、そちらを使えるなら利用したほうが良いですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問