コードをより「Python的に」高速にするために、「マルチプロセッシング」とマップ関数を使用して、a)関数とb)反復範囲を送信します。
埋め込まれたソリューション(つまり、tqdm.tqdm(range(0、30)の範囲でtqdmを直接呼び出す)は、マルチプロセッシングでは機能しません(以下のコードで定式化されています)。
進行状況バーは0から100%まで表示されます(pythonがコードを読み取るとき?)が、マップ関数の実際の進行状況を示していません。
「マップ」機能がどのステップにあるかを示すプログレスバーを表示する方法
from multiprocessing import Pool
import tqdm
import time
def _foo(my_number):
square = my_number * my_number
time.sleep(1)
return square
if __== '__main__':
p = Pool(2)
r = p.map(_foo, tqdm.tqdm(range(0, 30)))
p.close()
p.join()
ヘルプや提案は大歓迎です...
ソリューションが見つかりました:注意してください!マルチプロセッシングのため、推定時間(ループごとの反復、合計時間など)は不安定になる可能性がありますが、進行状況バーは完全に機能します。
注:プールのコンテキストマネージャーは、Pythonバージョン3.3からのみ使用可能です
from multiprocessing import Pool
import time
from tqdm import *
def _foo(my_number):
square = my_number * my_number
time.sleep(1)
return square
if __== '__main__':
with Pool(processes=2) as p:
max_ = 30
with tqdm(total=max_) as pbar:
for i, _ in tqdm(enumerate(p.imap_unordered(_foo, range(0, max_)))):
pbar.update()
処理された値の反復子を返すmapの代わりにimapを使用します。
from multiprocessing import Pool
import tqdm
import time
def _foo(my_number):
square = my_number * my_number
time.sleep(1)
return square
if __== '__main__':
with Pool(2) as p:
r = list(tqdm.tqdm(p.imap(_foo, range(30)), total=30))
xaviMartínezの答えに基づいて、関数imap_unordered_bar
を作成しました。 imap_unordered
と同じ方法で使用できますが、処理バーが表示される点が異なります。
from multiprocessing import Pool
import time
from tqdm import *
def imap_unordered_bar(func, args, n_processes = 2):
p = Pool(n_processes)
res_list = []
with tqdm(total = len(args)) as pbar:
for i, res in tqdm(enumerate(p.imap_unordered(func, args))):
pbar.update()
res_list.append(res)
pbar.close()
p.close()
p.join()
return res_list
def _foo(my_number):
square = my_number * my_number
time.sleep(1)
return square
if __== '__main__':
result = imap_unordered_bar(_foo, range(5))
代わりにp_tqdm
を使用できます。
https://github.com/swansonk14/p_tqdm
from p_tqdm import p_map
import time
def _foo(my_number):
square = my_number * my_number
time.sleep(1)
return square
if __== '__main__':
r = p_map(_foo, list(range(0, 30)))
このアプローチは簡単で、機能します。
from multiprocessing.pool import ThreadPool
import time
from tqdm import tqdm
def job():
time.sleep(1)
pbar.update()
pool = ThreadPool(5)
with tqdm(total=100) as pbar:
for i in range(100):
pool.apply_async(job)
pool.close()
pool.join()