2010-10-08 9 views

Répondre

15

J'ai tendance à utiliser inlineCallbacks pour une initialisation multi-étapes (telle que auth) vers un service où chaque étape suivante dépend du résultat de l'étape précédente, par exemple. Autres que ces situations, j'ai tendance à trouver que inlineCallbacks pourrait conduire à une programmation paresseuse qui pourrait ralentir votre application.

Voici un exemple:

@defer.inlineCallbacks 
def some_func(): 
    res1 = yield call1() 
    res2 = yield call2() 
    ... do something with res1 and res2 ... 

Si call1 et call2 sont complètement indépendants les appels que vous souhaitez paralléliser, cette fonction finira sérialisation ces appels. Pour convertir à un parallélisation appel, vous devez:

@defer.inlineCallbacks 
def some_func_better(): 
    d1 = call1() 
    d2 = call2() 
    res1 = yield d1 
    res2 = yield d2 

De cette façon, vous obtenez Call1 et Call2 en cours d'exécution en même temps, mais vous attendez les résultats comme ils viennent donc, alors qu'il est possible d'obtenir les mêmes avantages sur. stock différé, il semble inlineCallbacks juste le rendre trop facile à mettre en œuvre l'ancienne solution.

Aussi, gardez à l'esprit que vous avez encore à envelopper try...except blocs autour de tous vos appels de rendement, car ils sont la seule façon de piéger errbacks dans votre code (sauf si une fonction d'appel d'une fonction inlineCallbacks gère le errback à ce niveau).

Donc, je trouve que ce n'est pas vraiment une question de performances en soi, mais plutôt de bonnes habitudes qui me ferait recommander contre inlineCallbacksen général - ils sont toujours parfaits pour des extraits de code rapide, l'initialisation en plusieurs étapes routines, ou des tests par exemple.

+0

De manière surprenante, 'inlineCallbacks' ne supporte pas' cancel() '. Une fois, j'ai dû réécrire plusieurs fonctions prêtes à lire pour créer des constructions complexes de rappels imbriqués, car j'avais besoin d'annuler() le processus. – Stefan

2

Les différences devraient être vraiment subtiles. Si ce code fonctionne vraiment aussi souvent que cela a son importance, vous devriez peut-être examiner la conception de votre application. Sinon, prenez la variante qui est plus facile à lire, vous aurez à faire des têtes et des queues dans quelques mois ou quelques années sur la route.

EDIT: Si vous voulez vraiment savoir, voici comment vous le savez (il pourrait, après tout, être spécifique à l'implémentation de votre version python): exécutez les deux versions en boucle et mesurez l'heure. Augmentez le nombre de boucles jusqu'à ce que la différence de temps entre les versions soit bien supérieure à la variance de temps de la même version sur plusieurs cycles. Répéter après avoir changé la version python, le système d'exploitation etc.

+0

En outre, il est plus utile de faire ce test sur votre propre code d'application, car cela dépend de la façon dont vous les utilisez. – Glyph

0

utilisation defer.inlineCallbacks peut rendre vos codes easiler à lire ..

et en quelque sorte comme le style corountine: vous ne bloquer l'appel, ni utiliser la chaîne de callbacks pour construire toute la logique. C'est intuitif.