timeit Library document :https://docs.python.org/zh-cn/3/library/timeit.html
timeit Is a tool library used to measure the execution time of small code fragments , Yes Command line and Function call Two methods are available .
You can directly view the last... Of the document Sample section Learn its usage quickly .
Be careful :
It should be noted that , In command line , Pass to timeit Of stmt Parameters
( The test code to run ) Are in string format , Not function references or Python sentence . In the function , Except for Strings , You can pass in a callable object .
Command line mode :
If it's in windows Use the command line to execute the statement , Remember that the outermost layer needs to be used Double quotes
, Otherwise, an error will be reported .
$ python3 -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 5: 30.2 usec per loop
$ python3 -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 5: 27.5 usec per loop
$ python3 -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 5: 23.2 usec per loop
Function call :
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
0.3018611848820001
>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)
0.2727368790656328
>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)
0.23702679807320237
On function call , Callable objects can be passed in :
>>> timeit.timeit(lambda: "-".join(map(str, range(100))), number=10000)
0.19665591977536678
But notice ,timeit () The number of repetitions is automatically determined only when using the command line interface .
The module contains 3 Two common methods and one Timer class :
timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)
Using the given stmt、setup Code and timer Function to create a Timer example , And according to number Running it timeit () Method . Optional globals Parameter specifies the namespace in which the code is executed .
timeit.repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=5, number=1000000, globals=None)
Using the given stmt and setup Code and timer Function to create a Timer example , And use the given repeat Count and number Execute the... That runs it repeat () Method ( Default execution 5 * 1000000 Time ). Optional globals Parameter specifies the namespace in which the code is executed .
timeit.default_timer()
Default timer time.perf_counter()
.
*class* timeit.Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None)
Class for timing the execution speed of small code side . This category includes timeit(), autorange(), repeat() and print_exec()
Four ways .
The constructor accepts a statement to be timed stmt、 An additional statement for setting setup And a timer function . Both statements default to “ pass”; The timer function depends on the platform .Stmt and setup It can also contain information from ; Or multiple statements separated by newline , As long as they do not contain multiline string text . By default , Statement will execute in its namespace ; You can pass namespaces to globals Variable to control this behavior .
To measure the first statement stmt Execution time of , Please use timeit () Method .Repeat () and autOrange () Method is convenient for multiple calls timeit () Methods .setup The execution time of the statement is excluded from the entire timed execution run .
Stmt and setup Parameters can also accept callable objects without parameters (callable). This will embed calls to them in a timer function , Then from timeit () perform . Be careful , under these circumstances , Due to extra function calls , The timing overhead is a little high .
timeit(number=1000000)
:
The execution time of the subject sentence . This will carry out setup Statement once , Then it returns the time required to execute the subject sentence several times , In seconds Calculate as a floating-point number . The parameter is the number of times through the loop , The default is 100 Ten thousand times . Subject sentence 、 setup Statement and what to use timer The function is passed to the constructor .
Be careful : In the use of timeit() Function testing , It will be temporarily closed by default Python Garbage collection function of . The advantage of this method is that it makes independent timing more comparable . The disadvantage is that GC It may be an important part of the performance of the function being measured . If so ,GC Can be re enabled as the first statement in the setting string . timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit()
Creating Timer Object stmt Set in gc.enable()
.
autorange(callback=None)
:
Automatically determine the call timeit () The number of times .
This is a convenient function , Used to call repeatedly timeit () , Make total time > = 0.2 second , Return the final result ( The number of cycles and the time it takes ). It uses sequences 1、2、5、10.20、50 Incremental number call in timeit () , Until it takes at least 0.2 second .
If callback callback It is given. , And not None, Then it will be called with two parameters after each test : callback (number,time_taken)
.
repeat(repeat=5, number=1000000)
:
Call timer repeat Time .
This is a convenient function , It repeatedly calls timeit () , Return a list of results . The first parameter repeat Designated call timeit () The number of times . The second parameter specifies timeit () Of number Parameters .
Be careful : It is tempting to calculate the mean and standard deviation from the result vector and report these results . However , This is not very useful . In a typical example , The minimum value gives the lower limit of how fast your computer can run a given code fragment ; The higher value in the result vector is usually not determined by Python Caused by a change in speed , But because other processes interfere with the accuracy of the timing . therefore , The results of min () Probably the only number you should be interested in . after , You should look at the whole vector with common sense, not at the whole result from a statistical point of view .
print_exc(file=None)
:
Help program for printing backtracking from timing code .
t = Timer(...) # outside the try/except
try:
t.timeit(...) # or t.repeat(...)
except Exception:
t.print_exc()
The advantage over standard backtracking is , The source code lines in the compiled template are displayed . Optional file The parameter points to the location where the backtrace is sent ; It defaults to sys.stderr.
python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...]
-n timer perform statement The number of times
-r repeat timer The number of times , The default is 5
-u Appoint timer Output time format , Can be specified as :nsec、usec、msec、sec
-s setup sentence , The default is pass
-p Use time.process_time() Not the default time.perf_counter() To measure process time , Not wall clock time
-v Details , Print the original timing results
-h Help information
A multiline statement By using ; Divide into multiple statements , Indented lines can enclose a parameter in quotation marks and use leading spaces .-s The multiline syntax for options is similar .
$ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text'
5000000 loops, best of 5: 0.0877 usec per loop
$ python -m timeit -s 'text = "sample string"; char = "g"' 'text.find(char)'
1000000 loops, best of 5: 0.342 usec per loop
Use -s designated setup Statement is executed only once at the beginning .
There are three fields in the output :
The above statement uses functions and Timer The code for the class is as follows :
>>> import timeit
>>> timeit.timeit('char in text', setup='text = "sample string"; char = "g"')
0.41440500499993504
>>> timeit.timeit('text.find(char)', setup='text = "sample string"; char = "g"')
1.7246671520006203
>>> import timeit
>>> t = timeit.Timer('char in text', setup='text = "sample string"; char = "g"')
>>> t.timeit()
0.3955516149999312
>>> t.repeat()
[0.40183617287970225, 0.37027556854118704, 0.38344867356679524, 0.3712595970846668, 0.37866875250654886]
When statement When a statement contains multiple lines of statements , On the command line and Python The code can be executed as follows :
$ python -m timeit 'try:' ' str.__bool__' 'except AttributeError:' ' pass'
20000 loops, best of 5: 15.7 usec per loop
$ python -m timeit 'if hasattr(str, "__bool__"): pass'
50000 loops, best of 5: 4.26 usec per loop
$ python -m timeit 'try:' ' int.__bool__' 'except AttributeError:' ' pass'
200000 loops, best of 5: 1.43 usec per loop
$ python -m timeit 'if hasattr(int, "__bool__"): pass'
100000 loops, best of 5: 2.23 usec per loop
>>> import timeit
>>> # attribute is missing
>>> s = """\ ... try: ... str.__bool__ ... except AttributeError: ... pass ... """
>>> timeit.timeit(stmt=s, number=100000)
0.9138244460009446
>>> s = "if hasattr(str, '__bool__'): pass"
>>> timeit.timeit(stmt=s, number=100000)
0.5829014980008651
>>>
>>> # attribute is present
>>> s = """\ ... try: ... int.__bool__ ... except AttributeError: ... pass ... """
>>> timeit.timeit(stmt=s, number=100000)
0.04215312199994514
>>> s = "if hasattr(int, '__bool__'): pass"
>>> timeit.timeit(stmt=s, number=100000)
0.08588060699912603
When we want to measure the time of the function we define , Can pass setup Parameter passing is required in the script import sentence ( Even under the current script import:from __main__ import func
),stmt The parameter passing method calls the stringed expression :
def test():
"""Stupid test function"""
L = [i for i in range(100)]
if __name__ == '__main__':
import timeit
print(timeit.timeit("test()", setup="from __main__ import test"))
Another way is to globals Parameter passing globals()
function . This will cause the code to execute within the current global namespace . This may be more convenient than specifying the import separately :
def f(x):
return x**2
def g(x):
return x**4
def h(x):
return x**8
import timeit
print(timeit.timeit('[func(42) for func in (f,g,h)]', globals=globals()))
In [2]: def test():
...: a = 0
...: for _ in range(1000):
...: a += _
...:
In [3]: timeit.timeit('test()', globals=globals())
Out[3]: 35.442787599982694
In [4]: timeit.timeit('test()', number=1, globals=globals())
Out[4]: 3.50000336766243e-05
In [5]: timeit.timeit('test()', number=10, globals=globals())
Out[5]: 0.00033359997905790806
In [6]: timeit.timeit('test()', number=100, globals=globals())
Out[6]: 0.0032857999904081225
In [7]: timeit.timeit('test()', number=1000, globals=globals())
Out[7]: 0.03538430004846305
>python -m timeit "a=0" "for _ in range(1000):" " a+=_"
10000 loops, best of 5: 32.4 usec per loop
# In seconds
>python -m timeit -u sec "a=0" "for _ in range(1000):" " a+=_"
10000 loops, best of 5: 3.24e-05 sec per loop