最近学习 aiohttp 。
想试试 python motor 单条插入的总体时间。没想到需要 160 多秒。 如果用 pymongo 单条插入,不用 aiohttp 和 motor,总体时间只需要 23 秒。如果用 insert_many,总体时间只需要 1.4 秒
请问各位大佬,是我 aiohttp 或者 motor 做错了什么?
import asyncio,hashlib,time from aiohttp import web import motor.motor_asyncio motor_mongo_client = motor.motor_asyncio.AsyncIOMotorClient('127.0.0.1', 17177) async def mongodb_test(request): start_time = time.time() for i in range(100000): md5 = str(i) + u'a9cfb75778b38676' md5 = md5.encode('utf-8') md5 = hashlib.md5(md5).hexdigest() items = { 'md5': md5, 'i': i } try: await motor_mongo_client['mongodb_test']['insert_test'].insert_one(items) except Exception as e: print(e) continue end_time = time.time() const_time = end_time - start_time print(const_time) return web.Response(text="done") loop = asyncio.get_event_loop() app = web.Application(loop=loop) app.add_routes([ web.get('/index', index), web.get('/mongodb_test',mongodb_test), ]) web.run_app(app, host='127.0.0.1', port=8080)
![]() | 1 sivacohan PRO ![]() 切换上下文是有成本的。 await motor_mongo_client['mongodb_test']['insert_test'].insert_one(items) 这一句会导致每一次执行到这,都会切换一下上下文。所以导致会慢。 异步操作一般解决的是 IO 慢,导致整体并发不足的情况。在你的例子里,数据库 IO 并不是瓶颈,这个例子里,你应该使用多线程、或多进程。 |
![]() | 2 linw1995 2020-09-01 13:23:28 +08:00 &nsp; ![]() motor 实际就是 pymongo + 多线程,每次操作都要另外个线程去做,完成再回调到主线程。而直接用 pymongo 就是单个线程在跑,少了上下文切换,当然快啦。并发高速度慢,并发低速度快,根据业务情况取舍吧 |
![]() | 3 bnm965321 2020-09-01 13:27:05 +08:00 ![]() 可以直接 ensure_future 还是什么函数,把协程插入到事件循环就行不要让下一个协程等待上一个执行完毕 |
![]() | 4 676529483 2020-09-01 15:58:18 +08:00 ![]() 你 for 循环里面用 await 就变成单线程了,试试 create_task |
![]() | 5 Wincer 2020-09-01 18:59:12 +08:00 ![]() operatiOns= [] for 循环内部 await 改成: operations.append(motor_mongo_client['mongodb_test']['insert_test'].insert_one(items)) 然后 asyncio.gather(*operations),这才是正确的使用方法 |