测试代码执行时间的模块-timeit

有时候我们想看看一个函数的执行时间是多久,这时候我们可以使用装饰器,在函数的执行开始前,记录一个时间,在函数的执行结束后记录一个时间,然后求两个数的差,就可以得到这个函数本次的执行时间了。但是这样做的做法,太Low,接下来我们就说说Python 内置的timeit 模块

timeit 模块可以用来测试一小段Python 代码的执行速度
timeit 模块里面有一个Timer 类,首先需要实例化这个类,先看一下初始化这个类所可以接收的参数,下面是timeit 模块关于Timer 的源码

1 class Timer:
2     ...
3     def __init__(self, stmt="pass", setup="pass", timer=default_timer, globals=None)
4     ...

资料显示这个是Python2.3 更新的一个完美计时工具,可以测量Python 代码的运行时间。
首先Timer 是这个测量代码执行时间的类
这个类实例化时可接收的参数
    stmt:要测试的代码语句(statment)
    setup:运行代码时需要的设置,也就是要测试代码的前置条件
    timer:参数时一个定时器函数,与平台有关
    globals:待查,后续更新


这个类实例出来后有两个方法是我们经常用到的

Timer.timeit(number=default_number)
参数number 是测试代码时的测试次数,默认default_number 为1000000 次,这个方法返回执行代码的耗时,一个float 类型的秒数。

Timer.repeat(repeat=default_repeat, number=default_number)
参数repeat 是重复整个测试的次数,默认是重复3 次,参数number 是每个测试代码时的测试次数,默认也是1000000 次,
这个方法返回一个列表,元素的个数就是重复整个测试的次数,每个元素值就是每个测试代码的耗时,是一个float 类型的秒数。

由简单着手,具体如下:

 1 import timeit 
 2 # 创建timeit 对象
 3 timer_hello = timeit.Timer("print('hello'))
 4 # 调用timer 方法执行1000 次,并打印结果
 5 time_use = time_hello.timeit(1000)
 6 print('elapse :{}'.format(time_use))
 7 
 8 
 9 hello
10 ...
11 hello
12 elapse :0.07077193709161148

但是事实上没人会测试打印1000 次“hello”所用的时间,除非特别无聊,举这个例子只是为了方便直观的说明第二个参数的作用

 1 import timeit
 2 
 3 a = 'hello'
 4 
 5 timer_a = timeit.Timer("print(a)")
 6 time_use = time_a.timeit(1000)
 7 print('elapse :{}'.format(time_use))
 8 
 9 
10 ...
11 NameError: name 'a' is not defined

为什么会这样呢?明明已经定义了变量a 啊,为什么还是提示未定义?
这是因为这个类实例话的时候,会构建一个独立的虚拟空间用于测试待测试代码
只需要传入第二个参数就可以解决这个问题

 1 import timeit
 2 
 3 # a = 'hello'
 4 
 5 timer_a = timeit.Timer("print(a)",“a='hello'”)
 6 time_use = time_a.timeit(1000)
 7 print('elapse :{}'.format(time_use))
 8 
 9 hello
10 ...
11 elapse :0.038286632634104326
12 # 时间上会比直接打印‘hello’要稍微长一点

这样就没问题了,可是我们当初的目的是用来打印一个函数啊,难不成要在第二个参数上写一个函数,比如匿名函数f = lambda :print(‘hello’)?

 1 import timeit
 2 
 3 # a = 'hello'
 4 
 5 timer_a = timeit.Timer("f()",“f=lambda : print('hello')”)
 6 time_use = time_a.timeit(1000)
 7 print('elapse :{}'.format(time_use))
 8 
 9 hello
10 ...
11 elapse :0.014775986865789454

也没问题,但是这只是个简单的函数,如果函数的逻辑很复杂,代码量很多,这样就不太好用了,那怎么办呢?答案是导入,将当前模块导入到这个Timer 实例对象的环境中就行了

 1 import timeit
 2 
 3 # a = 'hello'
 4 def print_hello():
 5     print('hello')
 6 
 7 timer_a = timeit.Timer("print_hello()",“from __main__ import print_hello”)
 8 time_use = time_a.timeit(1000)
 9 print('elapse :{}'.format(time_use))
10 
11 
12 hello
13 ...
14 elapse :0.038094632804770844

 

下面是Python 中list 的一些操作测试

 1 def t1():
 2     l = []
 3     for i in range(1000):
 4     l = l + [i]
 5 def t2():
 6     l = []
 7     for i in range(1000):
 8     l.append(i)
 9 def t3():
10     l = [i for i in range(1000)]
11 def t4():
12     l = list(range(1000))
13 
14 import timeit
15 
16 time_t1 = timeit.Timer('t1()', 'from __main__ import t1')
17 print('concat use {} seconds'.format(time_t1.timeit(1000)))
18 time_t2 = timeit.Timer('t2()', 'from __main__ import t2')
19 print('append use {} seconds'.format(time_t2.timeit(1000)))
20 time_t3 = timeit.Timer('t3()', 'from __main__ import t3')
21 print('comprehension use {} seconds'.format(time_t3.timeit(1000)))
22 time_t4 = timeit.Timer('t4()', 'from __main__ import t4')
23 print('list range use {} seconds'.format(time_t4.timeit(1000)))
24 
25 concat use 1.1694602938130723 seconds
26 append use 0.0634083880814329 seconds
27 comprehension use 0.028811085501257327 seconds
28 list range use 0.009896880091662119 seconds

由此可以看出,Python 内置的list 函数强转的效率有多高,列表推导式仅次之,列表尾部添加元素的效率正常,而列表的拼接后重新引用的执行效率,则要差上很多了。

相对于append,我们看一下列表头部插入的执行效率

1 def t5():
2     l = []
3     for i in range(1000):
4     l.insert(0, i)
5 time_insert = timeit.Time('t5()', 'from __main__ import t5')
6 print('insert use {} seconds'.format(time_t5.timeit(1000)))
7 
8 insert use 0.2727046464847587 seconds

可以看出列表都不插入的效率比尾部插入的效率要低的多

 

最后再来说一说repeat 方法

print('append information :{}'.format(time_t2.repeat(4, 1000)))
print('insert information :{}'.format(time_t5.repeat(4, 1000)))



append information :[0.06173994512004878, 0.06133461214701143, 0.06315461052923509, 0.06169727849130799]
insert information :[0.26799709511369324, 0.26826598376357, 0.2789770853537018, 0.26663220743803784]

可以看出,对这些代码的运行,进行了输入个数的测试,并返回了一个列表,元素为每个测试的结果

 

转载于:https://www.cnblogs.com/yungiu/p/10392333.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 装饰器是 Python 中一种很常用的设计模式,它可以在不改变原函数的情况下,在原函数运行前后增加新的功能。 下面是一个简单的测试代码执行时间的装饰器的例子: ``` import time def timeit(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) end = time.perf_counter() print(f'Function {func.__name__} took {end - start:.6f} seconds') return result return wrapper @timeit def test_function(n): time.sleep(n) test_function(2) ``` 运行上面的代码,会输出 `Function test_function took 2.000400 seconds`,表示 `test_function` 函数执行了 2 秒。 希望这个例子能帮到你。 ### 回答2: 好的,下面是一个测试代码执行时间的装饰器示例: ```python import time def calculate_execution_time(func): def wrapper(*args, **kwargs): start_time = time.time() # 记录函数开始执行时间 result = func(*args, **kwargs) # 执行被装饰的函数 end_time = time.time() # 记录函数结束执行时间 execution_time = end_time - start_time # 计算函数执行时间 print("函数 {} 的执行时间为:{} 秒".format(func.__name__, execution_time)) return result # 返回函数执行结果 return wrapper # 使用装饰器来测试函数执行时间 @calculate_execution_time def example_function(n): # 模拟一个耗时操作 time.sleep(n) return "耗时操作完成" # 调用被装饰的函数 print(example_function(3)) # 传入参数3代表模拟耗时3秒的操作 ``` 这个装饰器函数`calculate_execution_time`接收一个函数作为参数,并返回一个新的函数作为装饰后的函数。在这个新函数内部,我们使用`time`模块来计算被装饰函数执行时间,并在函数结束后打印出来。 在示例中,我们将`example_function`函数使用`@calculate_execution_time`装饰器进行装饰,然后调用该函数并传入参数。装饰器会自动计算函数执行时间,并打印在控制台上。最后返回函数执行结果。 希望这个示例能帮助你编写自己的测试代码执行时间的装饰器。 ### 回答3: 当需要测试某段代码的执行时间时,可以使用装饰器来实现。一个简单的测试代码执行时间的装饰器可以按照如下方式实现: ```python import time def calculate_time(func): def wrapper(*args, **kwargs): start_time = time.time() # 记录开始时间 result = func(*args, **kwargs) # 执行被装饰的函数 end_time = time.time() # 记录结束时间 execution_time = end_time - start_time # 计算执行时间 print(f"函数 {func.__name__} 执行时间为 {execution_time} 秒") return result return wrapper ``` 上述代码中,`calculate_time` 是一个装饰器函数,它接受一个函数作为参数,并返回一个包装函数 `wrapper`。`wrapper` 函数执行被装饰的函数之前和之后分别记录了开始时间和结束时间,并计算出执行时间。最后,它打印出执行时间并返回原函数的结果。 使用该装饰器的方式是,在需要测试执行时间函数定义之前加上 `@calculate_time`。 例如: ```python @calculate_time def my_function(): # 执行一些代码 # ... pass my_function() # 测试代码执行时间 ``` 当你运行上述代码时,它将会打印出 `my_function` 函数执行时间。这样,你就可以方便地测试代码执行时间了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值