【问题标题】:Bottle returning responses very slowly瓶子返回响应非常缓慢
【发布时间】:2019-06-08 14:47:05
【问题描述】:

我已经创建了 2 种不同的方式从我的路由装饰函数之一返回:

方法一:

return HTTPResponse(status=200, body=myBody)

方法 2(这样做是为了让 after_request 挂钩读取相同的响应对象,目前。):

response = bottle.response.copy()
response.status = 200
response.body = myBody
return response

myBody 是一个字符串,而不是 dict(我们的上游库已经通过 json.dumps() 将 dict 转换为字符串),而且 myBody 也很大:它是一个有 1 个键的字典,但有 600 多个成员列表作为值。

我的问题是: 方法 1 返回调用客户端的速度非常快(客户端通过 POST 请求使用请求库)。

方法 2 大约慢了 10 倍(调用客户端等待大约 2 分钟才能获得响应,而方法 1 为 2 秒)。

我还禁用了任何 after_hook 逻辑,只是为了隔离任何其他影响。

有什么暗示可能是根本原因吗?

【问题讨论】:

  • 您为什么要复制响应而不是对其采取行动?
  • @eatmeimadanish 无论哪种方式,速度都很慢。
  • 只是好奇:一个典型的myBody 有多少字节?
  • @ronrothmanℝℝ 它是 2.4 兆字节。
  • 好的,是的,这已经足够大了,我希望看到性能上的差异。

标签: python web bottle


【解决方案1】:

返回大字符串最有效(最快)的方法是简单地返回一个可迭代对象。例如,

return [myBody]

特别是:(1)不要复制响应对象,(2)200是默认响应码,所以不需要指定。


问:为什么我返回一个列表(包含单个字符串)而不是字符串?

答:我们可以return myBody,但首选return [myBody]Here's why:

应用程序必须返回一个可迭代的产生字节字符串。您可能会返回一个字符串(因为字符串是可迭代的),但这会导致大多数服务器逐个字符地传输您的内容。

【讨论】:

  • 谢谢。除了不复制响应对象之外,您认为不将其作为列表传输会导致速度缓慢吗?但是为什么通过传递 myBody (也不是作为列表)将其作为 HTTPResponse 传输不会导致缓慢?
  • 是的,我的猜测是复制响应会更加损害性能。但只是一个猜测 - 幸运的是它很容易测试。让我们知道会发生什么,我很想知道
  • 返回 [myBody] 现在更快了! .copy() 并没有放慢多少。但是,为什么我将 myBody 发送到 HTTPresponse 并返回 HTTPResponse 时并不慢?我不应该也发送 [myBody] 吗?
  • 不,当你创建一个新的响应对象时,它是一个不同的代码路径。我猜你的字符串很大!
猜你喜欢
  • 1970-01-01
  • 2019-12-13
  • 2012-02-12
  • 1970-01-01
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
  • 2019-05-09
  • 2022-01-09
相关资源
最近更新 更多