[Python教程]Pythontimeit模块使⽤解析
timeit模块------准确测量⼩段代码的执⾏时间
timeit模块函数
该模块定义了三个使⽤函数和⼀个公共类
timeit.timeit(stmt=‘pass’, setup=‘pass’, timer=<default timer>, number=1000000)
创建⼀个Timer实例,参数分别是stmt(需要测量的语句或函数),setup(初始化代码或构建环境的导⼊语句),timer(计时函
数),number(每⼀次测量中语句被执⾏的次数)
注:由于timeit()正在执⾏语句,语句中如果存在返回值的话会阻⽌timeit()返回执⾏时间。timeit()会取代原语句中的返回值。
创建⼀个Timer实例,参数分别是stmt(需要测量的语句或函数),setup(初始化代码或构建环境的导
⼊语句),timer(计时函
数),repeat(重复测量的次数),number(每⼀次测量中语句被执⾏的次数)
timeit.default_timer()
默认的计时器,⼀般是time.perf_counter(),time.perf_counter()⽅法能够在任⼀平台提供最⾼精度的计时器(它也只是记录了⾃然时间,记录⾃然时间会被很多其他因素影响,例如计算机的负载)
class timeit.Timer(stmt=‘pass’, setup=‘pass’, timer=<timer function>)
计算⼩段代码执⾏速度的类,构造函数需要的参数有stmt,setup,timer。前两个参数的默认值都是’pass’,timer参数是平台相关的;前两个参数都可以包含多个语句,多个语句间使⽤分号(;)或新⾏隔开。
第⼀次测试语句的时间,可以使⽤timeit()⽅法;repeat()⽅法相当于持续多次调⽤timeit()⽅法并将结果返回为⼀个列表。
stmt和setup参数也可以是可供调⽤但没有参数的对象,这将会在⼀个计时函数中嵌套调⽤它们,然后被timeit()所执⾏。注意,由于额外的调⽤,计时开销会相对略多。
-timeit(number=1000000)
功能:计算语句执⾏number次的时间。
它会先执⾏⼀次setup参数的语句,然后计算stmt参数的语句执⾏number次的时间,返回值是以秒为单位的浮点数。number参数的默认值是⼀百万,stmt、setup和timer参数由timeit.Timer类的构造函数传递。
注意:默认情况下,timeit()在计时的时候会暂时关闭Python的垃圾回收机制。这样做的优点是计时结果更具有可⽐性,但缺点是
GC(garbage collection,垃圾回收机制的缩写)有时候是测量函数性能的⼀个重要组成部分。如果是这样的话,GC可以在setup参数执⾏第⼀条语句的时候被重新启动,例如:
timeit.Timer('for i in range(10):oct(i)','gc.enable()').timeit()
-repeat(repeat=3, number=1000000)
功能:重复调⽤timeit()。
repeat()⽅法相当于持续多次调⽤timeit()⽅法并将结果返回为⼀个列表。repeat参数指定重复的次数,number参数传递给timeit()⽅法的number参数。
注意:⼈们很容易计算出平均值和标准偏差,但这并不是⾮常有⽤。在典型的情况下,最低值取决于你的机器可以多快地运⾏给定的代码段;在结果中更⾼的那些值通常不是由于Python的速度导致,⽽是因为其他进程⼲扰了你的计时精度。所以,你所应感兴趣的只有结果的最低值(可以⽤min()求出)
-print_exc(file=None)
功能:输出计时代码的回溯(Traceback)
典型的⽤法:
t = Timer(...)# outside the try/except
try:
t.timeit(...)# peat(...)
except Exception:
t.print_exc()
标准回溯的优点是在编译模板中,源语句⾏会被显⽰出来。可选的file参数指定将回溯发送的位置,默认是发送到sys.stderr。
命令⾏界⾯
当被作为命令⾏程序调⽤时,可以使⽤下列选项:
python -m timeit [-n N][-r N][-s S][-t][-c][-h][statement ...]
各个选项的含义:
选项原型含义
-n N–number=N执⾏指定语句(段)的次数
-r N–repeat=N重复测量的次数(默认3次)
-s S–setup=S指定初始化代码或构建环境的导⼊语句(默认是pass)
-p–process测量进程时间⽽不是实际执⾏时间
以下是Python3.3以后新增
选项原型含义
-t–time使⽤time.time()(不推荐)
-c–clock使⽤time.clock()(不推荐)
-v–verbose打印原始的计时结果,输出更⼤精度的数值
-h–help打印⼀个简短的⽤法信息并退出
python操作实例
下⾯我测试了⼏种创建列表的⽅法,有函数法(append(),extend(),insert()),有创建新列表然后指向(+),有与extend()类似的+=,有列表⽣成器([i for i in range()]),有迭代器(list(range())),查看这⼏种⽅法分别是⽤了多长时间:
from timeit import Timer
def t1():
li =[]
for i in range(10000):
li = li +[i]
def t2():
li =[]
for i in range(10000):
li +=[i]
def t3():
li =[i for i in range(10000)]
def t4():
li =list(range(10000))
def t5():
li =[]
for i in range(10000):
li.append(i)
def t6():
li =[]
for i in range(10000):
def t7():
li =[]
for i in range(10000):
li.insert(0,i)
timer1 = Timer("t1()","from __main__ import t1") print("+:",timer1.timeit(1000))
timer2 = Timer("t2()","from __main__ import t2") print("+=:",timer2.timeit(1000))
timer3 = Timer("t3()","from __main__ import t3") print("[i for i in range(1000)]:",timer3.timeit(1000))
timer4 = Timer("t4()","from __main__ import t4") print("list(range(10000)):",timer4.timeit(1000))
timer5 = Timer("t5()","from __main__ import t5") print("append:",timer5.timeit(1000))
timer6 = Timer("t6()","from __main__ import t6") print("extend:",timer6.timeit(1000))
timer7 = Timer("t7()","from __main__ import t7") print("insert:",timer7.timeit(1000))
最后结果为:
+:165.18708997200883
+=:0.856570930001908
[i for i in range(1000)]:0.3371259919949807
list(range(10000)):0.1656288539961679 append:0.6853008780017262
extend:1.0690860609902302
insert:21.749674607999623
可以看出迭代器速度⾮常快,其次是列表⽣成器,再然后是append(),extend(),+=,最后是最慢的insert()与+,所以这⾥不推崇+的⽅法,看来以后要多使⽤列表⽣成器与迭代器,如果不是实在不⾏的情况下也不要使⽤insert()。
下⾯是列表内置操作的时间复杂度:
下⾯是字典内置操作的时间复杂度:
timeit源码
#! /usr/bin/env python3
"""Tool for measuring execution time of small code snippets.
This module avoids a number of common traps for measuring execution
times. See also Tim Peters' introduction to the Algorithms chapter in
the Python Cookbook, published by O'Reilly.
Library usage: see the Timer class.
Command line usage:
python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-p] [-h] [--] [statement]
Options:
-n/--number N: how many times to execute 'statement' (default: see below)
-r/--repeat N: how many times to repeat the timer (default 3)
-s/--setup S: statement to be executed once initially (default 'pass')
-p/--process: use time.process_time() (default is time.perf_counter())
-t/--time: use time.time() (deprecated)
-
c/--clock: use time.clock() (deprecated)
-v/--verbose: print raw timing results; repeat for more digits precision
-h/--help: print this usage message and exit
--: separate options from statement, use when statement starts with -
--: separate options from statement, use when statement starts with - statement: statement to be timed (default 'pass')
A multi-line statement may be given by specifying each line as a separate argument; indented lines are possible by enclosing an argument in quotes and using leading spaces. Multiple -s options are treated similarly.
If -n is not given, a suitable number of loops is calculated by trying successive powers of 10 until the total time is at least 0.2 seconds. Note: there is a certain baseline overhead associated with executing a pass statement. It differs between versions. The code here doesn't try to hide it, but you should be aware of it. The baseline overhead can be measured by invoking the program without arguments.
Classes:
Timer
Functions:
timeit(string, string) -> float
repeat(string, string) -> list
default_timer() -> float
"""
import gc
import sys
import time
import itertools
__all__ =["Timer","timeit","repeat","default_timer"]
dummy_src_name ="<timeit-src>"
default_number =1000000
default_repeat =3
default_timer = time.perf_counter
# Don't change the indentation of the template; the reindent() calls
# in Timer.__init__() depend on setup being indented 4 spaces and stmt # being indented 8 spaces.
template ="""
def inner(_it, _timer):
{setup}
_t0 = _timer()
for _i in _it:
{stmt}
timeout on t2 timer_t1 = _timer()
return _t1 - _t0
"""
def reindent(src, indent):
"""Helper to reindent a multi-line statement."""
place("\n","\n"+" "*indent)
def_template_func(setup, func):
"""Create a timer function. Used if the "statement" is a callable."""
def inner(_it, _timer, _func=func):
setup()
_t0 = _timer()
for _i in _it:
_func()
_t1 = _timer()
return _t1 - _t0
return inner
class Timer:
"""Class for timing execution speed of small code snippets.
The constructor takes a statement to be timed, an additional
statement used for setup, and a timer function. Both statements
default to 'pass'; the timer function is platform-dependent (see
module doc string).
To measure the execution time of the first statement, use the
timeit() method. The repeat() method is a convenience to call
timeit() multiple times and return a list of results.
The statements may contain newlines, as long as they don't contain multi-line string literals.
"""
def__init__(self, stmt="pass", setup="pass", timer=default_timer):
"""Constructor. See class doc string."""
self.timer = timer
ns ={}
if isinstance(stmt,str):
stmt = reindent(stmt,8)
if isinstance(setup,str):
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论