2016-06-20 47 views
7

Sto scrivendo un'API nel pallone che restituisce JSON. Ogni funzione beuta è della formaPerché il metodo jsonify del pallone è lento?

from flask import jsonify 
@app.route('/getdata') 
def get_data(): 
    data = load_data_as_dict() 
    return jsonify(data) 

Se ritorno una grande quantità di dati, una chiamata a questa funzione richiede circa 1,7 secondi. Tuttavia, se faccio questo:

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" 

... la funzione termina in circa 0,05 secondi.

Qualcuno può dirmi perché lo jsonify è molto più lento? C'è qualcosa di sbagliato nel restituire una risposta di Flask non elaborata?

Grazie!

+0

Possibile duplicato di [json.dumps vs flask.jsonify] (http://stackoverflow.com/questions/7907596/json-dumps-vs-flask-jsonify) – rnevius

+0

grazie, ho visto quel post e capisco la differenza. La mia domanda riguarda le prestazioni. –

risposta

5

La mia ipotesi è: ha molto a che fare con l'indentazione e fare un dump json pretty json. Ecco la definizione del metodo (ho messo a nudo i commenti per risparmiare spazio, il codice completo è disponibile here):

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 avvolge simplejson.dumps se il modulo è disponibile, altrimenti si usa json.dumps.

Quali prestazioni si ottengono se si esegue il codice con gli stessi argomenti?

+0

È vero, l'ho provato. Se ridefinisci jsonify e jsut remove indent, funzionerà molto più velocemente. Nel mio tempo di prova è passato da 17 a 0,1 secondi, 170 volte! – Rugnar

0

Dal documentation si afferma che:

Questa funzione avvolge discariche() per aggiungere un paio di miglioramenti che rendono più facile la vita . Trasforma l'output JSON in un oggetto Response con l'applicazione /mimetype json.

in modo che la stessa cosa, si finisce con un oggetto Reponse in entrambi i casi ma dal momento che si tratta di una funzione di convenienza, probabilmente lo fa più lavoro di quanto la sua controparte leggero, quindi il tempo supplementare.

EDIT: in realtà dopo guardando di nuovo la documentazione:

Per chiarezza, il comportamento di serializzazione JSON presenta le seguenti differenze da discariche(): singolo argomento: passata discariche().

Potete testare sia return jsonify(data) e return json.dumps(data)? Dovrebbero corrispondere.