Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

marshal python

+2 votes

Je suis utilisateur de python 2.7 depuis peu de temps, j'utilse la fonction magique "marshal" pour retourner un flux json.
en faisant un profile de mon petit programme pour voir où est que je passe plus de temps, je me suis apperçu que la fonction "marshal" prend plus de temps, est ce que quelqu'un à une idée?

Edit de boblinux :

Exemple simple

voila un exemple simple:

outputemail = {
   'email': fields.Raw,
   'visible': fields.Raw,
}
    outputphone = {
   'phone': fields.Raw,
   'visible': fields.Raw,
}
output_website = {
   'website': fields.Raw,
   'visible': fields.Raw,
}

outputcontact = {
   'emails': fields.List(fields.Nested(outputemail, allownull=True)),
   'phones': fields.List(fields.Nested(outputphone, allownull=True)),
   'websites': fields.List(fields.Nested(outputwebsite, allownull=True)),
}
outputcontacts ={
   'contacts':fields.List(fields.Nested(outputcontact, allownull=True))
}

marshal({'contacts': contacts}, output_contacts)

code test

!/usr/bin/env python
coding=utf-8

from flask_restful import marshal, fields

object1_marshaler ={
    "id": fields.String,
    "name": fields.String
}

object2marshaler = {
    "id": fields.String,
    "name": fields.String,
    "object1s": fields.List(fields.Nested(object1marshaler, allow_null=True))
}

object3marshaler = {
    "id": fields.String,
    "name": fields.String,
    "object2s": fields.List(fields.Nested(object2marshaler, allow_null=True))
}

object4marshaler = {
    "id": fields.String,
    "name": fields.String,
    "object3s": fields.List(fields.Nested(object3marshaler, allow_null=True))
}

responsemarshaler ={
    "object4s": fields.List(fields.Nested(object4marshaler, allow_null=True))
}

class Object1(object):
    def init(self, id, name):
        self.id=id
        self.name=name

class Object2(object):
    def init(self, id, name):
        self.id=id
        self.name=name
        self.object1s=[]

class Object3(object):

    def __init__(self, id, name):
        self.id=id
        self.name=name
        self.object2s=[]
class Object4(object):
    def init(self, id, name):
        self.id=id
        self.id=id
        self.name=name
        self.object3s=[]

def get_object4s():
    result = []

    for i in range(1000):
        object4 = Object4(i, i)
        for j in range(10):
            object3 = Object3(i,j)
            for k in range(10):
                object3.object2s.append(Object2(j, k))
            object4.object3s.append(object3)
        result.append(object4)
    return result
import flask, flask_restful

app = flask.Flask(name)
app.request_class = flask.Request

api = flaskrestful.Api(app, catchall404s=True)
api.app.urlmap.strict_slashes = False
import time

class Index(flask_restful.Resource):

    def get(self):
        t0 = time.clock()
        object4s = get_object4s()
        t0diff = time.clock() - t0
        t1 = time.clock()
        response = marshal({"object4s": object4s}, response_marshaler)

        return {'marshal' :{'time':time.clock() - t1, 'comment':'seconds process time'},
            'constructObject4':{'time':t0diff, 'comment':'seconds process time'}}, 200
    api.add_resource(Index,
    '/',
    '/index',
    endpoint='index')

from flask_script import Manager

manager = Manager(app)

if name == 'main':
    manager.run()

et le resultat de l'appel : curl http://127.0.0.1:5000/index
est :

    {
        "constructObject4": {
        "comment": "seconds process time", 
        "time": 1.1319289999999995
    }, 
    "marshal": {
        "comment": "seconds process time", 
        "time": 22.873293
    }
    }

on voit bien que temps passé dans le marshal et 20 fois le temps passé pour fabriquer les objets !!!

vous avez une explication?

demandé 23-Jul-2015 par moi
edité 20-Nov-2015 par boblinux

bonsoir,
il y a des traitements avant de renvoyer la réponse avec le marshal, accès à la base de données, decorators, ...
je constate avec le profiler que plus de la moitié du temps à fabriquer la réponse à partir de la liste d'objet!

Sans plus de détails c'est dur de savoir. Soit cette moitié du temps n'est pas significative, soit il y a une erreur dans la mesure (ie l'ORM qui fait des requetes) soit la fonction marshal de flask-Restful n'est pas efficace.

J'ai un peu de mal a voir comment le temps de marshal peut ne pas prendre en compte le temps d'acces à la base car c'est son utilisation basique : renvoyer une donnée sérializé a partir d'objets python. Si tu fais l'accès aux données en dehors, pourquoi utiliser marshal et ne pas construire directement la réponse ?

+1. Mesure l'accès en dehors de l'API pour voir ce que ça donne. Ce sera plus objectif.

@moi la moitié du temps, c'est vague: la moitié de quel temps (du temps pris par ton application, du temps pris pour une requête)

fabriquer la réponse à partir de la liste d'objet c'est vague aussi vu que si ta liste d'objet c'est un itérateur à partir d'une requête à la base de donnée ça peut très bien être ta requête en base de donnée qui prend du temps (en particulier si tu n'as pas mis d'index sur ta base de donnée.

si tu as du code et un profil d'exécution à mettre dans la question ce serait intéressant aussi

J'interviens sur le post pour faire un peu de ménage avec quelques éditions sur vous le permettez.

@ Moi :

  1. Essaye d'utiliser les balises de codage pour coller du code , (c'est le truc avec '{ }' déssiné, tu séléctionnes ton texte et clique dessus)
  2. On ne répond pas à une question par une question, j'ai mis ta "réponse" dans ta question initiale en édition ;)
  3. L'indentation du code c'est le bien, surtout en python ! (j'ai essayé d'indenter mais il peut y avoir des trucs bizarre à cause des 4 boucles for ibrmiquées..) si ton code est pas indenté, personne n'arrivera à le lire, encore moins à le tester (car python n'accepte le code non-indenté)
  4. Et (pour proposer tout de même un mini. de contenu) tant qu'à faire une lecture ici ne ferait pas de mal

Votre réponse

Preview

Votre nom à afficher ( en option ):
Vie privée: . Votre adresse de messagerie ne sera utilisée que pour l'envoi de ces notifications .
Vérification anti -spam:
Pour éviter cette vérification à l'avenir, Connectez vous ou inscrivez vous.
...