10. Debugging and Profiling¶
10.1. Timing¶
Does list comprehension run faster than map ?
$ python -m timeit 'list(map(str, range(10)))'
100000 loops, best of 3: 3.36 usec per loop
$ python -m timeit '[str(i) for i in range(10)]'
100000 loops, best of 3: 4.76 usec per loop
See also: Python List Comprehension Vs. Map
Equivalent to:
def timeit(setup, statements, repeat=3, number=1000000):
exec(setup)
for _ in range(repeat):
start = time.time()
for _ in range(number):
exec(statements)
cost = time.time() - start
Advanced control:
# -s: setup statement, run once
# -n: how many times to execute 'statement'
# -r: how many times to repeat the timer(default 3)
# multiple statements
$ python -m timeit -r 5 -n 1000 -s 'data=range(50)' 'l=[]' 'for i in data: l.append(i)'
1000 loops, best of 5: 6.76 usec per loop
$ python -m timeit -r 5 -n 1000 -s 'data=range(50)' 'l=[None]*50' 'for i in data: l[i]=i'
1000 loops, best of 5: 3.71 usec per loop
10.2. Profiling¶
$ python -m cProfile chapter10/grep.py pattern .
...
706259 function calls (673963 primitive calls) in 1.597 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <frozen importlib._bootstrap>:1000(__init__)
...
1 0.000 0.000 1.597 1.597 grep.py:1(<module>)
3409 0.192 0.000 0.644 0.000 grep.py:15(search_file)
702 0.001 0.000 0.002 0.000 grep.py:23(colored)
702 0.005 0.000 0.040 0.000 grep.py:27(print_matches)
6708 0.147 0.000 0.388 0.000 grep.py:34(is_binary)
1 0.058 0.058 1.594 1.594 grep.py:45(main)
1 0.000 0.000 0.003 0.003 grep.py:7(parse_args)
...
397099 0.128 0.000 0.128 0.000 {method 'search' of '_sre.SRE_Pattern' objects}
- ncalls
- for the number of calls,
- tottime
- for the total time spent in the given function (and excluding time made in calls to sub-functions)
- percall
- is the quotient of tottime divided by ncalls
- cumtime
- is the cumulative time spent in this and all subfunctions (from invocation till exit). This figure is accurate even for recursive functions.
- percall
- is the quotient of cumtime divided by primitive calls
10.3. Tracing¶
$ python -m trace --count grep.py pattern .
...
$ cat grep.cover
1: import os
1: import re
...
202: for i, line in enumerate(file.readlines()):
199: m = pattern.search(line)
199: if m:
13: print_matches(name, i+1, line, m)