mirror of https://github.com/django/django.git
Optimized lazy() by removing use of @total_ordering.
@total_ordering is slow. Using the following micro-benchmark (resultclasses intentionally omitted to narrow the scope): import cProfile from django.utils.functional import lazy def identity(x): return x cProfile.run("for i in range(10000): str(lazy(identity)(1))") Before: 380003 function calls in 0.304 seconds ncalls tottime percall cumtime percall filename:lineno(function) 1 0.016 0.016 0.304 0.304 <string>:1(<module>) 10000 0.002 0.000 0.002 0.000 bench.py:5(double) 10000 0.005 0.000 0.006 0.000 functional.py:100(__cast) 10000 0.007 0.000 0.013 0.000 functional.py:106(__str__) 10000 0.005 0.000 0.017 0.000 functional.py:140(__wrapper__) 10000 0.020 0.000 0.258 0.000 functional.py:60(lazy) 10000 0.039 0.000 0.039 0.000 functional.py:68(__proxy__) 10000 0.010 0.000 0.012 0.000 functional.py:77(__init__) 10000 0.002 0.000 0.002 0.000 functional.py:84(__prepare_class__) 10000 0.025 0.000 0.075 0.000 functools.py:186(total_ordering) 10000 0.015 0.000 0.028 0.000 functools.py:189(<setcomp>) 10000 0.024 0.000 0.044 0.000 functools.py:37(update_wrapper) 10000 0.005 0.000 0.005 0.000 functools.py:67(wraps) 10000 0.074 0.000 0.114 0.000 {built-in method builtins.__build_class__} 1 0.000 0.000 0.304 0.304 {built-in method builtins.exec} 150000 0.023 0.000 0.023 0.000 {built-in method builtins.getattr} 10000 0.004 0.000 0.004 0.000 {built-in method builtins.max} 80000 0.025 0.000 0.025 0.000 {built-in method builtins.setattr} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 10000 0.003 0.000 0.003 0.000 {method 'update' of 'dict' objects} After: 240003 function calls in 0.231 seconds ncalls tottime percall cumtime percall filename:lineno(function) 1 0.016 0.016 0.231 0.231 <string>:1(<module>) 10000 0.002 0.000 0.002 0.000 bench.py:5(double) 10000 0.006 0.000 0.012 0.000 functional.py:105(__str__) 10000 0.005 0.000 0.017 0.000 functional.py:159(__wrapper__) 10000 0.015 0.000 0.186 0.000 functional.py:60(lazy) 10000 0.022 0.000 0.022 0.000 functional.py:68(__proxy__) 10000 0.010 0.000 0.012 0.000 functional.py:76(__init__) 10000 0.002 0.000 0.002 0.000 functional.py:83(__prepare_class__) 10000 0.004 0.000 0.006 0.000 functional.py:99(__cast) 10000 0.023 0.000 0.043 0.000 functools.py:37(update_wrapper) 10000 0.004 0.000 0.004 0.000 functools.py:67(wraps) 10000 0.102 0.000 0.124 0.000 {built-in method builtins.__build_class__} 1 0.000 0.000 0.231 0.231 {built-in method builtins.exec} 70000 0.011 0.000 0.011 0.000 {built-in method builtins.getattr} 50000 0.007 0.000 0.007 0.000 {built-in method builtins.setattr} 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 10000 0.003 0.000 0.003 0.000 {method 'update' of 'dict' objects}
This commit is contained in:
parent
a57d5d9bbc
commit
ee36e101e8
|
@ -1,7 +1,7 @@
|
||||||
import copy
|
import copy
|
||||||
import itertools
|
import itertools
|
||||||
import operator
|
import operator
|
||||||
from functools import total_ordering, wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
class cached_property:
|
class cached_property:
|
||||||
|
@ -82,7 +82,6 @@ def lazy(func, *resultclasses):
|
||||||
function is evaluated on every access.
|
function is evaluated on every access.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@total_ordering
|
|
||||||
class __proxy__(Promise):
|
class __proxy__(Promise):
|
||||||
"""
|
"""
|
||||||
Encapsulate a function call and act as a proxy for methods that are
|
Encapsulate a function call and act as a proxy for methods that are
|
||||||
|
@ -144,11 +143,31 @@ def lazy(func, *resultclasses):
|
||||||
other = other.__cast()
|
other = other.__cast()
|
||||||
return self.__cast() == other
|
return self.__cast() == other
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
if isinstance(other, Promise):
|
||||||
|
other = other.__cast()
|
||||||
|
return self.__cast() != other
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
if isinstance(other, Promise):
|
if isinstance(other, Promise):
|
||||||
other = other.__cast()
|
other = other.__cast()
|
||||||
return self.__cast() < other
|
return self.__cast() < other
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if isinstance(other, Promise):
|
||||||
|
other = other.__cast()
|
||||||
|
return self.__cast() <= other
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if isinstance(other, Promise):
|
||||||
|
other = other.__cast()
|
||||||
|
return self.__cast() > other
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if isinstance(other, Promise):
|
||||||
|
other = other.__cast()
|
||||||
|
return self.__cast() >= other
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.__cast())
|
return hash(self.__cast())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue