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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

3回答

1367閲覧

pythonで高速に並列処理したい(データ保存+データ処理)

arumon

総合スコア20

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/06/29 05:14

編集2022/01/12 10:55

プログラミング初心者です。
pythonで並列処理をしたいのですが、
高速化できる方法はないでしょうか?

処理1:データの取得
処理2:データの処理

処理1でデータ保存し続け、処理2の方で随時処理したい。

私はconcurrent.futuresを使いました。

import time import concurrent.futures def func1(): while True: print("func1") time.sleep(1) def func2(): while True: print("func2") time.sleep(1) if __name__ == "__main__": executor = concurrent.futures.ThreadPoolExecutor(max_workers=2) executor.submit(func1) executor.submit(func2)

もっと高速化できる手法やこういったデータ保存と処理の並列に適切な処理はないでしょうか?
宜しくお願い致します。

※質問を追記します。
ざっくりした質問で失礼いたしました。

■処理1:Arduinoからデータを受け取り、xにデータを格納し続ける

ser = serial.Serial('COM4', 9600) str = ser.readline() x.append(str)

■処理2:上記xから随時データを取り出し、処理する

i = 0 while True: if x[i] > 10: print("aaa") i += 1 ``` 本コードなら処理1→処理2を連続しても処理時間に影響ないと思いますが、 あくまで処理1と処理2を並列して実施したい次第です。 何卒宜しくお願い致します。

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

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

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

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

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

mather

2018/06/29 05:28

ざっくりしすぎていてなんとも言えません。たとえば、取得と処理が一対一で実行されるものなら取得してから処理するまでを一つのワーカーにまかせて並列化することを考えたほうが効率がいいと思いますし、いくつか取得してまとまったデータを一度に処理するなら別のやり方を考える必要があります。あるいはFIFOキューなど外部のミドルウェアを使って実行する方法もあります。どのような方法を取るかはやりたいこと次第です。
hayataka2049

2018/06/29 05:36

データの取得、データの処理がそれぞれ具体的にどのようなもので、どこがボトルネックになるのか、どこを並列化できるのか等がわかると回答がつきやすいと思います
coco_bauer

2018/06/29 06:59

"time.sleep(1)"のような意味のない時間待ちをやめると1桁以上の高速化が期待できます。
guest

回答3

0

経験則ですがconcurrent.futuresは高速化に適しているとは思いません。処理の内容や入出力の性質にもよりますがasyncioの方が適している気がします。

追記

python

1from concurrent.futures import ThreadPoolExecutor as PoolExecutor 2from functools import partial 3from random import random 4from time import sleep 5 6 7def func1(): 8 fake_read = partial(input, "なんか入力してみてね。ちなみに空行で終了です。") 9 yield from iter(fake_read, "") 10 11 12def func2(x): 13 sleep(random()) 14 print("あなたが入力したのはこれね。", "->", x) 15 16 17def main(): 18 done = partial(print, "処理終わったよ。", "->") 19 with PoolExecutor() as pool: 20 for x in func1(): 21 f = pool.submit(func2, x) 22 f.add_done_callback(done) 23 24 25if __name__ == '__main__': 26 main()

投稿2018/06/29 06:07

編集2018/07/02 04:47
YouheiSakurai

総合スコア6142

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

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

arumon

2018/06/29 10:59

>YouheiSakuraiさん ご回答ありがとうございます。 素人で恐縮ですが、Webで調べた結果、asyncioの使い方が分かりませんでした(汗) もし宜しければ、分かりやすいサイトやコード例など示して頂けると幸いです。 大変申し訳ありません。
YouheiSakurai

2018/06/29 11:12

asyncioは取っ付きにくいですね。あと処理1を今見ましたけど、それだったらデータを受け取る処理1を起点にして処理2をワーカープールにsubmitするようにすればいいんじゃないですかね。
arumon

2018/06/30 06:53

>データを受け取る処理1を起点にして処理2をワーカープールにsubmitする ご説明ありがとうございます。 すみませんが、具体的にどのようにコードを書けばいいのか分かりません(汗) もし宜しければお手数ですが、参考になるものを教えて頂けないでしょうか? ちなみに下記を参考にしておりましたが、まだ理解できておりません、、、 https://docs.python.jp/3/library/multiprocessing.html
arumon

2018/07/02 02:59

すみません、しつこくて申し訳ありません。 お忙しいと思いますが、ご回答頂けると幸いです。
guest

0

一般的なキューでやりたいことではないでしょうか?

python

1from multiprocessing import Pool, Queue, Process 2import multiprocessing 3import time 4import random 5 6random.seed(0) 7 8def f0(q): 9 items = range(10) 10 for item in items: 11 q.put(item) 12 time.sleep(random.random()/10.) 13 14def f1(q): 15 wait_count = 0 16 max_wait_count = 100 17 while True: 18 print(q.qsize()) 19 if q.qsize() > 0: 20 wait_count = 0 21 item = q.get() 22 txt = "" 23 for i in range(item): 24 txt += f"{i:0>5}" 25 time.sleep(0.001) 26 print(txt) 27 else: 28 time.sleep(0.01) 29 wait_count += 1 30 if wait_count > max_wait_count: 31 break 32 33q = Queue() 34p0 = Process(target=f0, args=(q,)) 35p1 = Process(target=f1, args=(q,)) 36p0.start() 37p1.start() 38time.sleep(2) 39#print([q.get() for _ in range(q.qsize())])

投稿2018/07/03 21:47

mkgrei

総合スコア8560

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

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

0

python

1i = 0 2while True: 3 if x[i] > 10: 4 print("aaa") 5 i += 1

処理2を単純に並列化してしまうと、 x に値が入る前にインデックスの値のみが進んでしまってエラーが発生すると思います。
やはりArduinoからの入力ごとにスレッドを作るなりしてイベントベースで処理を実行するのが良いと思います。

投稿2018/06/29 12:47

mather

総合スコア6753

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

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

arumon

2018/07/02 02:59

連投、誠に申し訳ありませんが、ご回答頂けると幸いです。 よろしくお願い致します。
mather

2018/07/02 03:02

えーと、これでいいですか、と聞く前にまずは試してみましょう。 スレッドに関してはその資料を参考にすればいいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問