测试代码的执行时间:%time和%timeit

对于规模更大、运行时间更长的数据分析应用程序,你可能会希望测试一下各个部分或函数调用或语句的执行时间。你可能会希望了解某个复杂计算过程中到底是哪些函数占用的时间最多。幸运的是,在开发和测试代码的过程中,IPython能够让你轻松得到这些信息。使用内置的time模块及其time.clock和time.time函数手工测试代码执行时间是一件令人烦闷的事情,因为你必须编写许多一模一样的了无生趣的公式化代码:

import time
start = time.time()
for i in range(iterations):
    # 这里放一些待执行的代码
    elapsed_per = (time.time() - start) / iterations

由于这是一个非常常用的功能,所以IPython专门提供了两个魔术函数(%time和%timeit)以便自动完成该过程。%time一次执行一条语句,然后报告总体执行时间。假设我们有一大堆字符串,希望对几个“能够选出具有特殊前缀的字符串”的函数进行比较。下面是一个拥有60万字符串的数组,以及两个不同的“能够选出其中以foo开头的字符串”的方法:

# 一个非常大的字符串数组
strings = ['foo', 'foobar', 'baz', 'qux', 'python', 'Guido Van Rossum'] * 100000
method1 = [x for x in strings if x.startswith('foo')]
method2 = [x for x in strings if x[:3] == 'foo']

看上去它们的性能表现应该差不多,对吧?我们通过%time来确认一下:

In [561]: %time method1 = [x for x in strings if x.startswith('foo')]
CPU times: user 0.19 s, sys: 0.00 s, total: 0.19 s
Wall time: 0.19 s

In [562]: %time method2 = [x for x in strings if x[:3] == 'foo']
CPU times: user 0.09 s, sys: 0.00 s, total: 0.09 s
Wall time: 0.09 s

墙上时间(Wall time)是我们最感兴趣的数字。所以,看上去第一个方法耗费了两倍以上的时间,但这并不是一个非常精确的结果。如果你对相同语句多次执行%time的话,就会发现其结果是会变的。为了得到更为精确的结果,需要使用魔术函数%timeit。对于任意语句,它会自动多次执行以产生一个非常精确的平均执行时间。

In [563]: %timeit [x for x in strings if x.startswith('foo')]
10 loops, best of 3: 159 ms per loop
  
In [564]: %timeit [x for x in strings if x[:3] == 'foo']
10 loops, best of 3: 59.3 ms per loop

这个貌似平淡无奇的例子正好说明了一个事实:我们非常有必要了解Python标准库、NumPy、pandas以及本书中所用到的其他库的性能特点。在大型数据分析应用程序中,这些不起眼的毫秒数是会不断累积的!

对于那些执行时间非常短(甚至是那些微秒(1e-6秒)或纳秒(1e-9秒)级的)的分析语句和函数而言,%timeit是非常有用的。虽然这些时间值小到几乎可以忽略不计,但同样执行100万次一个20微秒的函数,所用的时间要比一个5微秒的多15秒。在上面那个例子中,我们可以直接对那两个字符串运算进行比较以了解其性能特点:

In [565]: x = 'foobar'

In [566]: y = 'foo'

In [567]: %timeit x.startswith(y)
1000000 loops, best of 3: 267 ns per loop

In [568]: %timeit x[:3] == y
10000000 loops, best of 3: 147 ns per loop 
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答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` 函数的执行时间。这样,你就可以方便地测试代码执行时间了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值