2016年04月23日

pythonで並列ループ

jobidのParallelを使うと便利らしい

$ sudo pip install joblib
# コアの数の取り方
import multiprocessing
core_count = multiprocessing.cpu_count()

# とりあえずコアの半分だけ使おうか
job_count = int(core_count / 2)

# 行う処理
def foo( i ):
    return i ** 2

# 並列実行
import joblib
joblib.Parallel(n_jobs=job_count)(joblib.delayed(foo)(i) for i in range(10))  
  #=> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

実に簡単。

ところで並列で処理した結果をlistにappendするとかは大丈夫だろうか。

Pythonのlist appendはthread-safeらしいことを書いてあるけど、下記のようなコードはアカンらしい。

lst = []

def foo( i ):
    lst.append(i)
    print(lst)

# 並列実行
import joblib
joblib.Parallel(n_jobs=4)(joblib.delayed(foo)(i) for i in range(10))  
  # => [0]
  # => [1]
  # => [2]
  # => [3]
  # => [0, 4]
  # => [1, 5]
  # => [2, 6]
  # => [0, 4, 7]
  # => [2, 6, 8]
  # => [2, 6, 8, 9]

まあ、こういう使い方はしなくてもいいようにちゃんと書こう。