私はpymongoのパフォーマンスの改善を見たいと思っていますが、私は何も観察していません。スレッドを使用してpymongoのパフォーマンスを改善するにはどうすればよいですか?
私のサンプルデータベースには400,000レコードがあります。基本的には、スレッド化されシングルスレッド化されたパフォーマンスが同等であることがわかりました。
pymongoはクエリ中にGILを解放しませんか?
シングルパフォーマンス・:リアル0m0.618s
Multiproc:リアル0m0.144s
マルチスレッド:リアル0m0.656s
正規コード:今すぐ
choices = ['foo','bar','baz']
def regular_read(db, sample_choice):
rows = db.test_samples.find({'choice':sample_choice})
return 42 # done to remove calculations from the picture
def main():
client = MongoClient('localhost', 27017)
db = client['test-async']
for sample_choice in choices:
regular_read(db, sample_choice)
if __name__ == '__main__':
main()
$ time python3 mongotest_read.py
real 0m0.618s
user 0m0.085s
sys 0m0.018s
私はマルチプロセッシングを使用私はいくつかの改善を見ることができます。
from random import randint, choice
import functools
from pymongo import MongoClient
from concurrent import futures
choices = ['foo','bar','baz']
MAX_WORKERS = 4
def regular_read(sample_choice):
client = MongoClient('localhost', 27017,connect=False)
db = client['test-async']
rows = db.test_samples.find({'choice':sample_choice})
#return sum(r['data'] for r in rows)
return 42
def main():
f = functools.partial(regular_read)
with futures.ProcessPoolExecutor(MAX_WORKERS) as executor:
res = executor.map(f, choices)
print(list(res))
return len(list(res))
if __name__ == '__main__':
main()
$ time python3 mongotest_proc_read.py
[42, 42, 42]
real 0m0.144s
user 0m0.106s
sys 0m0.041s
しかし、ProcessPoolExecutorからThreadPoolExecutorに切り替えると、スピードはシングルスレッドモードに戻ります。
...
def main():
client = MongoClient('localhost', 27017,connect=False)
f = functools.partial(regular_read, client)
with futures.ThreadPoolExecutor(MAX_WORKERS) as executor:
res = executor.map(f, choices)
print(list(res))
return len(list(res))
$ time python3 mongotest_thread_read.py
[42, 42, 42]
real 0m0.656s
user 0m0.111s
sys 0m0.024s
...
私はまた、それぞれのスレッドにそれ自身のMongoClientを与えてみました - 結果は同じです。 – MPaz