[1.8.x] Optimized allow_lazy() by not generating a new lazy wrapper on each invocation.

This dramatically improves performance on PyPy. The following benchmark:

python -mtimeit -s "from django.utils.functional import allow_lazy; from django.utils.translation import ugettext_lazy; f = allow_lazy(lambda s: s, str)" "f(ugettext_lazy('abc'))"

goes from 390us per loop to 165us.

Backport of 82e0cd1571 from master
This commit is contained in:
Alex Gaynor 2015-02-08 12:14:30 -06:00 committed by Tim Graham
parent b44a56c308
commit ee86bf24d2
1 changed files with 3 additions and 1 deletions

View File

@ -205,6 +205,8 @@ def allow_lazy(func, *resultclasses):
immediately, otherwise a __proxy__ is returned that will evaluate the
function when needed.
"""
lazy_func = lazy(func, *resultclasses)
@wraps(func)
def wrapper(*args, **kwargs):
for arg in list(args) + list(six.itervalues(kwargs)):
@ -212,7 +214,7 @@ def allow_lazy(func, *resultclasses):
break
else:
return func(*args, **kwargs)
return lazy(func, *resultclasses)(*args, **kwargs)
return lazy_func(*args, **kwargs)
return wrapper
empty = object()