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

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

ただいまの
回答率

87.92%

Pythonでのマルチスレッドを使用した、組み込み関数openによる複数ファイルIOは高速化が見込めるのでしょうか

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,333

score 31

PythonのマルチスレッドはGILによって基本的に1プロセスで1スレッドしか動かないということなので、あるプログラムを10スレッドで実行したとしても、実行するスレッドは1つでそれを高速に切り替えて平行に実行すると認識しています。
そのような動作ではCPUの計算リソースを多く使う処理をマルチスレッドにしても意味はなく、IO処理などスリープする時間が存在する処理しか高速化が期待できないらしいのですが、

質問としては以下のようにPythonの組み込み関数openを使用した複数ファイルIOをマルチスレッド処理することで高速化は期待できるのでしょうか?

from concurrent.futures import ThreadPoolExecutor

def read_file(file_name):
    f = open(filename, "r")
    text = f.read()
    f.close()
    return text

file_list = [str(i) + ".txt" for i in range(100)]

with ThreadPoolExecutor(max_workers=100) as executor:
    results = executor.map(read_file, file_list)
    results = list(results)

Pythonの組み込み関数openはマルチスレッドによって高速化されるような、スリープする時間はあるのでしょうか?
また、上の例はファイルの内容を読み込む処理ですが逆にファイルに内容を書き込む処理でも同様でしょうか?
教えてくださるとありがたいです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

ディスクの種類によると思います。
HDDの場合はマルチスレッドにしようが物理的に高速化出来ません。
NVMe対応SSDだとマルチスレッドで高速化が見込めるようですが、シーケンシャルアクセスだとさほど差は無いようです。
Windows 10世代のパーツ選び SSD編

ディスクIOそのものがボトルネックになるので、細かいデータを何回にも分けて書き込むと遅くなります。基本的に、メモリにバッファリングして多くのデータを一括で書き込んだ方が効率がいいです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

複数ファイルIOをマルチスレッド処理することで高速化は期待できるのでしょうか?

「高速化」の意味が逐次に処理する場合に比べて速くなるのか?ということであれば、答えは Yes です。
例えば、

  1. ファイルを読み出す(ディスクI/O依存処理) 1秒かかる
  2. 加工処理をする(CPU依存処理) 1秒かかる
  3. 結果をネットワークに書き出す(ネットワークI/O依存処理) 1秒かかる

これを10個のファイルに対して順次に行うと 30秒かかりますが、マルチスレッドにすることにより、異なるリソースの消費が並列化されますので、処理にかかる全体時間はうまくいけば 1/3 の約10秒で終わるでしょう。(厳密にはオーバヘッドや最初は同じリソースが競合するなどの問題があって、そうはなりません)
逆に単一のリソースがネックになるようなプログラム(例えば、処理時間のほとんどがディスクI/Oであるような場合)であれば、リソースの消費が並列化できないので、高速化は期待できないでしょう。
しかし、一般論で質問されていると仮定して答えは Yes だと思います。

もし、「高速化」の意味がディスクI/Oが並列化されて高速化されるのか?という意味であれば、答えは No です。

Pythonの組み込み関数openはマルチスレッドによって高速化されるような、スリープする時間はあるのでしょうか?

一般的に I/O のシステムコールは CPU ではないリソースを消費するので、CPUにとっては I/O 待ちになる場合が多く、CPUのリソースは空いた状態になります。これをスリープと呼ぶならスリープすると言えるでしょう。

上の例はファイルの内容を読み込む処理ですが逆にファイルに内容を書き込む処理でも同様でしょうか?

前述のとおり、 I/O のシステムコールは CPU ではないリソースを消費するという意味で書き込みでも読み出しでも同じです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ファイルアクセスは並列化できないので、期待できません

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/10/01 18:51

    ありがとうございます
    マルチスレッドではなくマルチプロセスで上の処理を行った場合、ファイルアクセスが並列になされるので高速化は期待できる認識で合っていますか?

    キャンセル

  • 2020/10/01 18:54

    マルチプロセスにしようが、同一の物理ディスクに対するファイルアクセスは並列化できません
    せいぜいアクセス間の処理時間がケチれるぐらいですね

    ファイルアクセスと、CPUでの処理って組み合わせなら並列できますね

    キャンセル

  • 2020/10/01 19:08

    ありがとうございます
    つまり、ファイルアクセスを並列化するためにはそれぞれのファイルが別のディスクに分散していなければ不可能ということなのですね
    その場合はマルチスレッドを使っても並列に読み込めるのでしょうか?

    キャンセル

  • 2020/10/01 19:15

    別の物理ディスクであれば並列化は期待できるでしょうけど、今度はインターフェース(SATA)の転送がどうかって話になりますね
    まあ、こっちは転送速度の上限までは期待できますが

    キャンセル

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

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • Pythonでのマルチスレッドを使用した、組み込み関数openによる複数ファイルIOは高速化が見込めるのでしょうか