IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python timeit库测试代码片段运行时间 -> 正文阅读

[Python知识库]Python timeit库测试代码片段运行时间

timeit库文档:https://docs.python.org/zh-cn/3/library/timeit.html


timeit 是一个用来测量小代码片段执行时间的工具库,有命令行函数调用两种方法可供使用。

可以直接查看文档最后的示例部分快速了解其用法。
注意

  • 使用函数调用时,timeit()方法的返回值以秒为单位,而且返回的是代码语句运行number次(timeit方法的参数)的总耗时,不是多次运行取最好结果/平均结果。
  • 在在命令行中,使用timeit语句返回结果是多次循环所花费的平均时间,时间单位可以指定。

基本示例:

需要注意的是,在命令行,传给timeit 的 stmt 参数(即要运行的测试代码)都要是字符串格式的,而不是函数引用或Python语句。在函数中,除了字符串,可以传入一个可调用对象。

  1. 命令行方式:
    如果是在windows下使用命令行执行语句,切记最外层需要使用双引号,否则会报错。

    $ 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
    
  2. 函数调用:

    >>> 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
    

    在函数调用时,可以传入可调用对象:

    >>> timeit.timeit(lambda: "-".join(map(str, range(100))), number=10000)
    0.19665591977536678
    

但是请注意,timeit ()只有在使用命令行界面时才会自动确定重复次数。


Python接口(函数调用)的使用方法:

模块包含3个常用方法和一个Timer类:

  • timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None)
    使用给定的stmt、setup代码和timer函数创建一个 Timer 实例,并根据number运行它的 timeit ()方法。可选的 globals 参数指定在其中执行代码的命名空间。

  • timeit.repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=5, number=1000000, globals=None)
    使用给定的stmt和setup代码和timer函数创建一个 Timer 实例,并使用给定的repeat计数和number执行运行它的 repeat ()方法(默认执行5 * 1000000次)。可选的 globals 参数指定在其中执行代码的命名空间。

  • timeit.default_timer()
    默认的计时器 time.perf_counter().

  • *class* timeit.Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None)
    用于计时小代码端执行速度的类。该类包括timeit(), autorange(), repeat()和print_exec()四个方法。

    构造函数接受一条要计时的语句stmt、一条用于设置的附加语句setup和一个计时器函数。这两个语句都默认为“ pass”; 计时器函数依赖于平台。Stmt 和 setup 还可以包含由; 或换行分隔的多个语句,只要它们不包含多行字符串文字。默认情况下,语句将在其名称空间内执行; 可以通过将名称空间传递给globals变量来控制此行为。

    若要度量第一个语句stmt的执行时间,请使用 timeit ()方法。Repeat ()和 autOrange ()方法是方便多次调用 timeit ()的方法。setup语句的执行时间被排除在整个计时执行运行之外。

    Stmt 和 setup 参数还可以接受不带参数的可调用对象(callable)。这将把对它们的调用嵌入到一个计时器函数中,然后由 timeit ()执行。注意,在这种情况下,由于额外的函数调用,计时开销有点大。

    • timeit(number=1000000)
      主语句的执行时间。这会执行 setup 语句一次,然后返回执行主语句若干次所需的时间,以秒为单位作为浮点数进行计算。参数是通过循环的次数,默认为100万次。主语句、 setup 语句和要使用的 timer 函数被传递给构造函数。

      注意:在使用timeit()函数测试时,默认会临时关闭Python的垃圾回收功能。这种方法的优点是它使独立计时更具可比性。缺点是 GC 可能是被测量函数性能的重要组成部分。如果是这样,GC 可以作为设置字符串中的第一条语句重新启用。 timeit.Timer('for i in range(10): oct(i)', 'gc.enable()').timeit() 在创建Timer对象时的stmt中设置gc.enable()

    • autorange(callback=None)
      自动确定调用 timeit ()的次数。
      这是一个便捷函数,用来反复调用 timeit () ,使总时间 > = 0.2秒,返回最终结果(循环次数和循环花费的时间)。它使用序列1、2、5、10.20、50中的递增数字调用 timeit () ,直到所花费的时间至少为0.2秒。
      如果回调callback是给定的,并且不是 None,那么在每次试验之后将使用两个参数调用它: callback (number,time_taken)

    • repeat(repeat=5, number=1000000)
      调用计时器repeat次。
      这是一个便捷函数,它重复调用 timeit () ,返回一个结果列表。第一个参数repeat指定调用 timeit ()的次数。第二个参数指定 timeit ()的 number 参数。
      注意:从结果向量计算平均值和标准差并报告这些结果是很有诱惑力的。然而,这并不是很有用。在一个典型的例子中,最低值给出了您的计算机运行给定代码片段的速度的下限; 结果向量中较高的值通常不是由 Python 速度的变化引起的,而是由于其他进程干扰了计时的准确性。因此,结果的 min ()可能是您应该感兴趣的唯一数字。之后,您应该用常识看待整个向量而不是从统计的角度看待整个结果。

    • print_exc(file=None)
      从计时代码打印回溯的帮助程序。

      t = Timer(...)       # outside the try/except
      try:
          t.timeit(...)    # or t.repeat(...)
      except Exception:
          t.print_exc()
      

      相对于标准回溯的优势在于,将显示已编译模板中的源代码行。可选的 file 参数指向发送回溯的位置; 它默认为 sys.stderr。


命令行接口:

python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...]
-n timer执行statement的次数
-r 重复执行timer的次数,默认为5
-u 指定timer输出的时间格式,可以指定为:nsec、usec、msec、sec
-s setup 语句,默认为pass
-p 使用time.process_time()而不是默认的time.perf_counter()来度量进程时间,而不是墙钟时间
-v 详细信息,打印原始的计时结果
-h 帮助信息

一个多行的statement可以通过使用 ; 分给为多个语句,带缩进的行可以使用引号括起一个参数并使用前导空格。-s选项的多行语法是类似的。


示例:

$ 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

使用-s 指定的setup语句只在开始时执行一次。
在输出中有三个字段:

  • loop count:告诉您每次计时循环重复运行语句体的次数。
  • repetition count:(best of 5)告诉您计时循环重复的次数。
  • 平均耗时:语句主体在计时循环的最佳重复范围内所花费的平均时间。

以上语句使用函数和Timer类的代码如下:

>>> 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]

多行语句:

当statement语句中包含多行语句时,在命令行和Python代码中可以如下执行:

$ 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

测试函数运行时间:

当要对我们定义的函数进行时间测量时,可以通过setup参数传递脚本中需要的 import 语句(即使是在当前脚本下也要import:from __main__ import func),stmt 参数传递方法调用字符串化后的表达式:

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"))

另一种方法是向globals参数传递 globals()函数。这将导致代码在当前全局命名空间内执行。这可能比单独指定进口更方便:

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()))

函数调用与命令行调用返回结果的差异:

  • 函数调用中timeit()方法的返回值,单位为秒,而且返回的是运行number次的总用时,不是平均用时。
  • 命令行中返回的结果是循环的平均用时,单位可以自行指定。
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
# 以秒为单位
>python -m timeit -u sec "a=0" "for _ in range(1000):" "  a+=_" 
10000 loops, best of 5: 3.24e-05 sec per loop
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:52:04  更:2022-06-26 16:52:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 3:36:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计