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.
This commit is contained in:
Alex Gaynor 2015-02-08 12:14:30 -06:00 committed by Tim Graham
parent 32e6a7d3a5
commit 82e0cd1571
1 changed files with 3 additions and 1 deletions

View File

@ -180,6 +180,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)):
@ -187,7 +189,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()