python-asyncio - 为什么异步比同步慢?
问题描述
为什么当我开始测试服务器上的负载时,同步编写方式的运行速度比异步方式快数百倍。我只是在尝试异步,我做错了什么?
ab -t 10 -n 10000 -c 100 http://127.0.0.1:8888/api/db/sync/ 每秒请求数:35
ab -t 10 -n 10000 -c 100 http://127.0.0.1:8888/api/db/ 每秒请求数:0.37
import asyncio
import json
import time
from asyncio import sleep
from typing import Optional, Union
import tornado.ioloop
import tornado.web
from jinja2 import Environment, select_autoescape, FileSystemLoader
from sqlalchemy import text, create_engine
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, Session
from tornado import gen
from tornado.httpserver import HTTPServer
env = Environment(
loader=FileSystemLoader('templates'),
autoescape=select_autoescape()
)
async_engine = create_async_engine(
"postgresql+asyncpg://***:***@localhost:5431/***",
echo=True,
)
async_session = sessionmaker(
async_engine, expire_on_commit=False, class_=AsyncSession
)
engine = create_engine(
"postgresql://***:***@localhost:5431/***",
echo=True,
)
sync_session = sessionmaker(
engine, expire_on_commit=False
)
class ApiDbHandler(tornado.web.RequestHandler):
def prepare(self):
header = "Content-Type"
body = "application/json"
self.set_header(header, body)
async def get(self):
async with async_session() as session:
session: AsyncSession
for result in await asyncio.gather(
session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1')),
session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1')),
session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')),
session.execute(
text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1')),
):
self.write(
json.dumps(result.fetchall(), default=str)
)
class ApiDbSyncHandler(tornado.web.RequestHandler):
def prepare(self):
header = "Content-Type"
body = "application/json"
self.set_header(header, body)
def get(self):
with sync_session() as session:
session: Session
assets = session.execute(text('SELECT * from *** where client_id = :bis_id').bindparams(bis_id='bis1'))
self.write(
json.dumps(assets.fetchall(), default=str)
)
ili = session.execute(text('SELECT * from *** where bis_id = :bis_id').bindparams(bis_id='bis1'))
self.write(
json.dumps(ili.fetchall(), default=str)
)
securities = session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
self.write(
json.dumps(securities.fetchall(), default=str)
)
abs_accounts = session.execute(text('SELECT * from *** where abs_id = :abs_id').bindparams(abs_id='abs1'))
self.write(
json.dumps(abs_accounts.fetchall(), default=str)
)
def make_app():
return tornado.web.Application([
(r"/api/db/", ApiDbHandler),
(r"/api/db/sync/", ApiDbSyncHandler),
])
if __name__ == "__main__":
app = make_app()
server = HTTPServer(app)
server.listen(8888)
tornado.ioloop.IOLoop.current().start()
解决方案
推荐阅读
- javascript - 在 Javascript Promise 中返回 'resolve' 函数
- ios - 故事板文件更改后如何获取新的本地化字符串
- c# - 使用 FirefoxDriver 获取页面源
- java - 如何在 Kotlin 中使用 Lambda handleHeavyContent()
- android - 更新 chrome 版本 76 后 android 应用程序崩溃
- join - spring-data-elasticsearch es6.7.2 保存子抛出异常:连接字段缺少路由
- python - 如何一次请求多个链接并稍后用scrapy解析它们?
- c++ - 在 C++17 和 emplace_back(...) 中保证复制省略
- linux - 获取映射共享内存的大小
- python - 比较特定列上的 2 个数据框