我写了一个 fastapi 应用程序。现在我正在考虑部署它,但是我似乎遇到了奇怪的意外性能问题,这似乎取决于我使用 uvicorn 还是 gunicorn。特别是如果我使用 gunicorn,所有代码(甚至标准库纯 python 代码)似乎都会变慢。对于性能调试,我编写了一个小应用程序来演示这一点:
import asyncio, time
from fastapi import FastAPI, Path
from datetime import datetime
app = FastAPI()
@app.get("/delay/{delay1}/{delay2}")
async def get_delay(
delay1: float = Path(..., title="Nonblocking time taken to respond"),
delay2: float = Path(..., title="Blocking time taken to respond"),
):
total_start_time = datetime.now()
times = []
for i in range(100):
start_time = datetime.now()
await asyncio.sleep(delay1)
time.sleep(delay2)
times.append(str(datetime.now()-start_time))
return {"delays":[delay1,delay2],"total_time_taken":str(datetime.now()-total_start_time),"times":times}
Run Code Online (Sandbox Code Playgroud)
使用以下命令运行 fastapi appi:
gunicorn api.performance_test:app -b localhost:8001 -k uvicorn.workers.UvicornWorker --workers 1
Run Code Online (Sandbox Code Playgroud)
get to 的响应体 …
考虑以下交互式示例
>>> l=imap(str,xrange(1,4))
>>> list(l)
['1', '2', '3']
>>> list(l)
[]
Run Code Online (Sandbox Code Playgroud)
有没有人知道是否已经在某处实现了一个版本的imap(和其他itertools函数),这样第二次执行列表(l)就会得到与第一次相同的结果.而且我不想要常规地图,因为如果使用更大的范围,在内存中构建整个输出可能会浪费内存.
我想要的东西基本上就像是
class cmap:
def __init__(self, function, *iterators):
self._function = function
self._iterators = iterators
def __iter__(self):
return itertools.imap(self._function, *self._iterators)
def __len__(self):
return min( map(len, self._iterators) )
Run Code Online (Sandbox Code Playgroud)
但如果有人已经这样做,那么对所有itertools手动执行此操作将是浪费时间.
PS.你认为容器比迭代器更禅,因为对于迭代器而言
for i in iterator:
do something
Run Code Online (Sandbox Code Playgroud)
当您明确需要删除元素的容器时,隐式清空迭代器.
我正在尝试调试我编写的一些代码,这涉及很多并行进程.并且有一些不需要的行为涉及输出sys.stdout和某些消息被打印两次.出于调试目的,知道某个点是否sys.stdout已被刷新将是非常有用的.我想知道这是否可能,如果是的话,怎么样?
PS.我不知道它是否重要但我使用OS X(至少一些sys命令取决于操作系统).