[英]Why is flask's jsonify method slow?
我正在燒瓶中寫一個返回json的API。 每個燒瓶功能都是這種形式
from flask import jsonify
@app.route('/getdata')
def get_data():
data = load_data_as_dict()
return jsonify(data)
如果我返回大量數據,則對此函數的調用大約需要1.7秒。 但是,如果我這樣做:
from flask import Response
@app.route('/getdata')
def get_data():
data = load_data_as_dict()
data_as_str = json.dumps(data)
return Response(response=data_as_str, status=200, mimetype="application/json"
...該功能在.05秒左右完成。
誰能告訴我為什么jsonify
會慢得多? 返回原始Flask響應有什么問題嗎?
我的猜測是:它與縮進和制作pretty
json轉儲有很大關系。 這是方法定義(我刪除了注釋以節省空間,完整代碼可以在這里找到):
def jsonify(*args, **kwargs):
indent = None
separators = (',', ':')
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not request.is_xhr:
indent = 2
separators = (', ', ': ')
if args and kwargs:
raise TypeError('jsonify() behavior undefined when passed both args and kwargs')
elif len(args) == 1: # single args are passed directly to dumps()
data = args[0]
else:
data = args or kwargs
return current_app.response_class(
(dumps(data, indent=indent, separators=separators), '\n'),
mimetype=current_app.config['JSONIFY_MIMETYPE']
)
dumps
包裝simplejson.dumps
如果模塊是可用的,否則,使用json.dumps
。
jsonify()
只包裝了json.dumps()
。 但是,根據Flask應用程序的配置和您正在使用的Flask版本,它可能會將indent=2
和separators=(', ', ': ')
傳遞給json.dumps
。 (如果您不熟悉這些參數,請參閱https://docs.python.org/3/library/json.html上關於漂亮打印的文檔)。
傳遞這些參數會大大減慢json.dumps
速度。 使用來自https://github.com/zemirco/sf-city-lots-json的181MB citylots.json
文件作為樣本數據,這些漂亮的打印參數將json.dumps()
的運行時間從7秒增加到31秒我的MacBook Pro:
>>> import time
>>> import json
>>> citylots = json.load(open('citylots.json'))
>>> start = time.time(); x = json.dumps(citylots); print(time.time() - start)
7.165302753448486
>>> x = None
>>> start = time.time(); x = json.dumps(citylots, indent=2, separators=(', ', ': ')); print(time.time() - start)
31.19125771522522
由於瓶1.0,這個昂貴的漂亮打印會發生,如果任一 :
JSONIFY_PRETTYPRINT_REGULAR
設置為True
(默認情況下為False
),或者 (您可以在Flask 1.0.2代碼中查看這些條件, 網址為https://github.com/pallets/flask/blob/1.0.2/flask/json/__init__.py#L309 。)
如果你使用Flask> = 1.0並且即使在調試模式下也有(可能不尋常)需要禁用漂亮的打印,你總是可以通過復制和粘貼內置的jsonify
定義並刪除所有的jsonify
來實現自己的jsonify
。漂亮的印刷邏輯:
from flask import current_app
from json import dumps
def jsonify(*args, **kwargs):
if args and kwargs:
raise TypeError('jsonify() behavior undefined when passed both args and kwargs')
elif len(args) == 1: # single args are passed directly to dumps()
data = args[0]
else:
data = args or kwargs
return current_app.response_class(
dumps(data) + '\n',
mimetype=current_app.config['JSONIFY_MIMETYPE']
)
如果您使用的是1.0 之前的 Flask版本,那么如果兩者都發生漂亮打印:
JSONIFY_PRETTYPRINT_REGULAR
顯式設置為False
(默認情況下為True
),AND 在那些舊版本中,永遠不需要重新定義jsonify
以消除漂亮的打印,因為您可以這樣做:
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
(或者,如果您使用的是1.0之前版本的Flask並且只想禁用生產中的漂亮打印,則無需更改代碼;而只需升級到最新版本的Flask。)
我花了一段時間才弄清楚,但Flask jsonify
在編碼器上設置了sort_keys
參數,它似乎默認為True
。
添加:
JSON_SORT_KEYS = False
對於更大的JSON結構,配置為我提供了7倍的加速。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.