【发布时间】:2016-11-21 08:58:04
【问题描述】:
我正在尝试查看 pymongo 的性能改进,但我没有观察到任何改进。
我的示例数据库有 400,000 条记录。从本质上讲,我看到线程和单线程的性能是相同的 - 唯一的性能提升来自多进程执行。
pymongo 在查询期间不会释放 GIL 吗?
单次性能:真实0m0.618s
Multiproc:real 0m0.144s
多线程:real 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 - 结果是一样的。
标签: multithreading performance pymongo