contracts
contracts copied to clipboard
Poor performance due to namedtuple construction in build_call
Is this performance to be expected? There seems to be a lot of time spent in building namedtuples...
$ python --version
Python 3.6.6 :: Anaconda, Inc.
$ cat test_dp.py
import sys
from dpcontracts import require
if sys.argv[1] == "dp":
@require("something about x", lambda args: args.x is not None)
def hot_method(x):
pass
else:
def hot_method(x):
pass
for i in range(100000):
hot_method(i)
$ python test_dp.py nodp
python test_dp.py nodp 0.05s user 0.00s system 98% cpu 0.053 total
$ python test_dp.py dp
python test_dp.py dp 29.19s user 0.02s system 99% cpu 29.284 total
# turned down to 10,000 iters...
$ python -m cProfile -stottime test_dp.py dp
775121 function calls (765029 primitive calls) in 3.144 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10019/1 2.109 0.000 3.283 3.283 {built-in method builtins.exec}
10028 0.194 0.000 0.261 0.000 {built-in method builtins.__build_class__}
10010 0.129 0.000 2.756 0.000 __init__.py:357(namedtuple)
10000 0.119 0.000 3.221 0.000 dpcontracts.py:437(build_call)
30110 0.085 0.000 0.085 0.000 {method 'format' of 'str' objects}
10001 0.078 0.000 0.182 0.000 inspect.py:2095(_signature_from_function)
10001 0.055 0.000 0.312 0.000 inspect.py:1082(getfullargspec)
10001 0.040 0.000 0.233 0.000 inspect.py:2176(_signature_from_callable)
10001 0.039 0.000 0.051 0.000 inspect.py:2725(__init__)
10000 0.032 0.000 3.260 0.000 dpcontracts.py:502(inner)
From a quick look, it seems like the tuple type only needs to be built on the first call. It can then be reused for further calls. Let me know if you would be interested in a patch.
See pull request #21