Why is flask's jsonify method slow?
我正在用烧瓶编写返回json的API。每个烧瓶函数的形式为
1 2 3 4 5 | from flask import jsonify @app.route('/getdata') def get_data(): data = load_data_as_dict() return jsonify(data) |
如果我返回大量数据,则对该函数的调用大约需要1.7秒。但是,如果我这样做:
1 2 3 4 5 6 | 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" |
...该功能在大约0.05秒内完成。
谁能告诉我为什么
我的猜测是:它与缩进和进行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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), '\ '), mimetype=current_app.config['JSONIFY_MIMETYPE'] ) |
传递这些参数会大大降低
1 2 3 4 5 6 7 8 | >>> 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 |
从Flask 1.0开始,如果出现以下情况之一,则会发生这种昂贵的精美印刷:
-
您已在应用程序的配置中将
JSONIFY_PRETTYPRINT_REGULAR 显式设置为True (默认为False ),或者 - 您正在以调试模式运行应用
(您可以在https://github.com/pallets/flask/blob/1.0.2/flask/json/__init__.py#L309的Flask 1.0.2代码中看到这些条件。)
如果您正在使用Flask> = 1.0,并且(甚至在调试模式下)需要禁用漂亮打印,则始终可以通过复制并粘贴内置的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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) + '\ ', mimetype=current_app.config['JSONIFY_MIMETYPE'] ) |
如果您使用的是Flask 1.0之前的版本,则如果同时出现以下两种情况,则会进行漂亮的打印:
-
您尚未在应用程序的配置中将
JSONIFY_PRETTYPRINT_REGULAR 设置为False (默认为True ),并且 - 当前请求不是XHR请求
在那些较旧的版本中,无需重新定义
1 | app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False |
(或者,如果您使用的是Flask的1.0之前版本,并且只想禁用生产环境中的漂亮打印,则无需更改代码;相反,只需升级到最新版本的Flask。 )
我花了一些时间才弄清楚,但是Flask
添加:
1 | JSON_SORT_KEYS = False |
该配置使我可以将大型JSON结构的速度提高7倍。