Twisted Deferred.addCallBack () против yield и @inlineDeferred - PullRequest
10 голосов
/ 09 октября 2010

Есть ли причина использовать один над другим?

Они имеют одинаковую производительность?

Ответы [ 3 ]

15 голосов
/ 17 октября 2010

Я склонен использовать inlineCallbacks для многоэтапной инициализации (например, аутентификации) для некоторого сервиса, где каждый последующий шаг зависит, например, от результата предыдущего шага. Помимо этих ситуаций, я обнаружил, что inlineCallbacks может привести к ленивому программированию, которое может замедлить ваше приложение.

Вот пример:

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

Если call1 и call2 являются полностью независимыми вызовами, которые вы хотите распараллелить, эта функция завершит сериализацию этих вызовов. Чтобы преобразовать это в распараллеливающий вызов, вы должны:

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

Таким образом, вы выполняете вызовы call1 и call2 одновременно, но вы ожидаете результатов по мере их поступления. Так что, хотя можно получить те же преимущества от отсрочки запасов, кажется, inlineCallbacks просто делает слишком легким реализовать прежнее решение.

Кроме того, имейте в виду, что вам все еще нужно обернуть блоки try...except вокруг всех ваших вызовов yield, поскольку они являются единственным способом отловить ошибки в вашем коде (если только вызывающая функция inlineCallbacks не обрабатывает ошибаться на этом уровне).

Итак, я считаю, что на самом деле это не вопрос производительности как таковой, а скорее хороших привычек, которые я бы рекомендовал против inlineCallbacks в целом - они все еще великолепны для быстрых фрагментов кода, многоэтапных процедур инициализации или тестов, например.

2 голосов
/ 09 октября 2010

Различия действительно должны быть тонкими.Если этот код действительно выполняется так часто, что это имеет значение, возможно, вам следует изучить дизайн приложения.В противном случае, возьмите вариант, который легче читать, вам придется сделать из него пару голов или хвостов спустя пару месяцев или лет.

РЕДАКТИРОВАТЬ: Если вы действительноХотите узнать, вот как вы узнаете (это может, в конце концов, быть реализацией, специфичной для вашей версии Python): запустите обе версии в тесном цикле и измерьте время.Увеличивайте число циклов, пока разница во времени между версиями не станет намного больше, чем разница во времени одной и той же версии при нескольких запусках.Повторите после изменения версии Python, ОС и т. Д.

0 голосов
/ 14 декабря 2011

использование defer.inlineCallbacks может облегчить чтение ваших кодов ..

и это как-то похоже на стиль corountine: вы не блокируете вызов и не используете цепочку обратных вызовов для построения всей логики. Это интуитивно понятно.

...