5

python计算函数执行时长的方法

 2 years ago
source link: https://www.fly63.com/article/detial/12114
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

python开发,有时需要做性能分析及性能优化,这时就需要记录一些耗时函数执行时间问题,然后针对函数逻辑进行优化。

在python3中一般都有哪些方法呢。

1、使用time.time()

这种方法较简单,但如果想更精确的计算函数的执行时间,会产生精度缺失,没办法统计时间极短的函数耗时。

import time
 
 def func():
     time.sleep(1)
     
 t = time.time()
 func()
 print(f'耗时:{time.time() - t:.4f}s')
 
 耗时:1.0050s

2、使用time.perf_counter()

perf_counter是在python3.3新添加的,返回性能计数器的值,返回值是浮点型,统计结果包括睡眠的时间,单个函数的返回值无意义,只有多次运行取差值的结果才是有效的函数执行时间。

import time
 def func():
     print('hello world')
 t = time.perf_counter()
 func()
 print(f'耗时:{time.perf_counter() - t:.8f}s')
 hello world
 耗时:0.00051790s

3、使用timeit.timeit ()

timeit()函数有5个参数:
   stmt 参数是需要执行的语句,默认为 pass
   setup 参数是用来执行初始化代码或构建环境的语句,默认为 pass
   timer 是计时器,默认是 perf_counter()
   number 是执行次数,默认为一百万
   globals 用来指定要运行代码的命名空间,默认为 None 
 import timeit
 def func():
     print('hello world')
 print(f'耗时: {timeit.timeit(stmt=func, number=1)}')
 hello world
 耗时: 0.0007705999999999824

4、使用装饰器统计

在实际项目代码中,可以通过装饰器方便的统计函数运行耗时。使用装饰器来统计函数执行耗时的好处是对函数的入侵性小,易于编写和修改。

装饰器装饰函数的方案只适用于统计函数的运行耗时,如果有代码块耗时统计的需求就不能用了,这种情况下可以使用 with 语句自动管理上下文。

(1)同步函数的统计

import time 
 def coast_time(func):
     def fun(*args, **kwargs):
         t = time.perf_counter()
         result = func(*args, **kwargs)
         print(f'函数:{func.__name__} 耗时:{time.perf_counter() - t:.8f} s')
         return result
     return fun
 @coast_time
 def test():
     print('hello world')
 if __name__ == '__main__':
     test()

(2)异步函数的统计

import asyncio
 import time
 from asyncio.coroutines import iscoroutinefunction
 def coast_time(func):
     def fun(*args, **kwargs):
         t = time.perf_counter()
         result = func(*args, **kwargs)
         print(f'函数:{func.__name__} 耗时:{time.perf_counter() - t:.8f} s')
         return result
     async def func_async(*args, **kwargs):
         t = time.perf_counter()
         result = await func(*args, **kwargs)
         print(f'函数:{func.__name__} 耗时:{time.perf_counter() - t:.8f} s')
         return result
     if iscoroutinefunction(func):
         return func_async
     else:
         return fun
 @coast_time
 def test():
     print('hello test')
     time.sleep(1)
 @coast_time
 async def test_async():
     print('hello test_async')
     await asyncio.sleep(1)
 if __name__ == '__main__':
     test()
     asyncio.get_event_loop().run_until_complete(test_async())       
 hello test
 函数:test 耗时:1.00230700 s
 hello test_async
 函数:test_async 耗时:1.00572550 s

5、with语句统计

通过实现 enter 和 exit 函数可以在进入和退出上下文时进行一些自定义动作,例如连接或断开数据库、打开或 关闭文件、记录开始或结束时间等,例如:我们用来统计函数块的执行时间。

with语句不仅可以统计代码块的执行时间,也可以统计函数的执行时间,还可以统计多个函数的执行时间之和,相比装饰器来说对代码的入侵性比较大,不易于修改,好处是使用起来比较灵活,不用写过多的重复代码。

import asyncio
 import time 
 class CoastTime(object):
     def __init__(self):
         self.t = 0
     def __enter__(self):
         self.t = time.perf_counter()
         return self
     def __exit__(self, exc_type, exc_val, exc_tb):
         print(f'耗时:{time.perf_counter() - self.t:.8f} s')
 def test():
     print('hello test')
     with CoastTime():
         time.sleep(1)
 async def test_async():
     print('hello test_async')
     with CoastTime():
         await asyncio.sleep(1)
 if __name__ == '__main__':
     test()
     asyncio.get_event_loop().run_until_complete(test_async())
hello test
耗时:1.00723310 s
hello test_async
耗时:1.00366820 s

来源:https://www.toutiao.com/article/7141037855584829990

链接: https://www.fly63.com/article/detial/12114


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK