首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Werkzeug响应太慢

Werkzeug响应太慢
EN

Stack Overflow用户
提问于 2013-05-28 05:24:45
回答 3查看 2.2K关注 0票数 4

我有以下Werkzeug应用程序,用于将文件返回给客户端:

代码语言:javascript
复制
from werkzeug.wrappers import Request, Response

@Request.application
def application(request):    
    fileObj = file(r'C:\test.pdf','rb')
    response = Response( response=fileObj.read() )
    response.headers['content-type'] = 'application/pdf'
    return response

我想要关注的部分是这一个:

代码语言:javascript
复制
response = Response( response=fileObj.read() )

在这种情况下,响应大约需要500毫秒(C:\test.pdf是一个4 MB的文件。Web服务器在我的本地机器上)。

但如果我将这一行重写为:

代码语言:javascript
复制
response = Response()
response.response = fileObj

现在响应大约需要1500毫秒。(速度慢3倍)

如果这样写的话:

代码语言:javascript
复制
response = Response()
response.response = fileObj.read()

现在响应大约需要80秒(没错,80秒)。

为什么这三种方法之间有这么大的差异?

为什么第三种方法这么慢呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-28 10:40:50

经过一些测试,我想我已经发现了其中的奥秘。

@Armin已经解释了为什么.

代码语言:javascript
复制
response = Response()
response.response = fileObj.read()

...is太慢了。但这不能解释为什么这..。

代码语言:javascript
复制
response = Response( response=fileObj.read() )

...is太快了。它们看起来是一回事,但显然不是。否则,在速度上就不会有那么大的差别。

这里的关键在于文档的这一部分:http://werkzeug.pocoo.org/docs/wrappers/

响应可以是任何类型的可迭代或字符串。如果它是一个字符串,它被认为是一个带有一个项目的迭代器,这就是传递的字符串。

也就是说,当你给构造器一个字符串时,它被转换成一个迭代器,这个字符串是它唯一的元素。但当您执行以下操作时:response.response = fileObj.read(),该字符串将按原样处理。

因此,要使其行为类似于构造函数,您必须这样做:

代码语言:javascript
复制
response.response = [ fileObj.read() ]

现在,文件会以最快的速度发送。

票数 4
EN

Stack Overflow用户

发布于 2013-05-28 07:41:54

这个问题的答案很简单:

  • x.read() <-将整个文件读入内存,inefficient
  • setting对文件的响应:效率非常低,因为该对象的协议是迭代器。因此,您将逐行发送文件。如果它是二进制的,你将会以随机的块大小发送它。
  • response设置为字符串:这是个坏主意。如前所述,它是一个迭代器,因此您现在将字符串中的每个字符作为单独的包发送。

正确的解决方案是将文件包装在WSGI服务器提供的文件包装器中:

代码语言:javascript
复制
from werkzeug.wsgi import wrap_file
return Response(wrap_file(environ, yourfile), direct_passthrough=True)

direct_passthrough标志是必需的,这样响应对象就不会试图遍历文件包装器,而是让WSGI服务器保持不变。

票数 8
EN

Stack Overflow用户

发布于 2013-05-28 07:02:45

我不能给你一个确切的答案,为什么会发生这种情况,但是http://werkzeug.pocoo.org/docs/wsgi/#werkzeug.wsgi.wrap_file可能会帮助你解决下属的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16780731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档