鱼C论坛

 找回密码
 立即注册
查看: 1669|回复: 7

[已解决]关于time模块的perf_counter与process_time

[复制链接]
发表于 2020-2-21 14:25:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
快把小甲鱼的零基础python学完了,这里碰到了一个问题,课后作业要求我们写一个计时器,计算(测试)函数的运行时间:

                               
登录/注册后可看大图


这里使用process_time就无法计时,无论如何输出的时间都是0.0000s
网上说的那些什么cpu进程时间之类的我真的不理解,求教。。
代码如下:

  1. import time
  2. class Timer:
  3.     start_time = 0
  4.     end_time = 0
  5.     workingTime = 0
  6.     mode = 1
  7.     def __init__(self,func,times = 1):
  8.         print("可以使用set_timer方法改变计时器的运行模式")
  9.         print("传入1使用 perf_counter ,传入2使用 process_time")
  10.         print("默认计时方式为 perf_counter")
  11.         self.times = times
  12.         self.func = func
  13.     def __str__(self):
  14.         return_str = "计时器运行了" + str(self.workingTime) + "秒"
  15.         return return_str
  16.     def __repr__(self):
  17.         return_str = "计时器运行了" + str(self.workingTime) + "秒"
  18.         return return_str
  19.    
  20.     def set_timer(self,mode):
  21.         if mode == 1:
  22.             self.mode == mode
  23.             print("修改成功,计时模式为 perf_counter")
  24.         if mode == 2:
  25.             print("修改成功,计时模式为 process_time")
  26.             self.mode == mode
  27.    
  28.     def start(self):
  29.         if self.mode == 1:
  30.             self.strat_time = time.perf_counter()
  31.             print("计时开始!")
  32.         if self.mode == 2:
  33.             self.start_time = time.process_time()
  34.             print("计时开始!")

  35.     def stop(self):
  36.         if self.mode == 1:
  37.             self.end_time = time.perf_counter()
  38.             self.workingTime = self.end_time - self.start_time
  39.             print("计时结束!")
  40.             print("计时器运行了%f秒"%(self.workingTime))
  41.         if self.mode == 2:
  42.             self.end_time = time.process_time()
  43.             self.workingTime = self.end_time - self.start_time
  44.             print("计时结束!")
  45.             print("计时器运行了%f秒"%(self.workingTime))

  46.     def timing(self):
  47.         self.mode = 2
  48.         self.start()
  49.         for i in range(self.times):
  50.             self.func
  51.         self.stop()


  52. def func1():
  53.     print("Hello World")

  54. t1 = Timer(func1,100)

  55. t1.timing()
复制代码

这里使用process_time作为计时模式时输出如下:

                               
登录/注册后可看大图

最佳答案
2020-2-21 15:43:05
Kituro_ 发表于 2020-2-21 15:29
好的谢谢呢,不过为什么在采用perf_counter进行计时的时候,第五十三行的self.func不加括号也可以正常运 ...

不加括号也能运行是因为 func 是一个函数签名,也就是这个函数的地址,所以你这个程序相当于
  1. for i in range(k):
  2.     id(5)
复制代码

这样子写是不会报错的。
运行倒是能正常运行,可是根本就没进行什么打印或计算,,连赋值这种操作都没有,而且那个函数也根本没运行,所以就没耗费什么时间,趋近于0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-21 15:17:01 | 显示全部楼层
第53行改成
  1. self.func()
复制代码


还有
  1. t1 = Timer(func1,100)
复制代码

第二个参数改大一点,改个1w-100w 之间吧,这样比较明显一些。

最后,你的程序复用性太低了,可以再简洁一点的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-2-21 15:29:02 | 显示全部楼层

好的谢谢呢,不过为什么在采用perf_counter进行计时的时候,第五十三行的self.func不加括号也可以正常运行呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-21 15:30:00 | 显示全部楼层

复用性太低是指代码不够简洁吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 15:43:05 | 显示全部楼层    本楼为最佳答案   
Kituro_ 发表于 2020-2-21 15:29
好的谢谢呢,不过为什么在采用perf_counter进行计时的时候,第五十三行的self.func不加括号也可以正常运 ...

不加括号也能运行是因为 func 是一个函数签名,也就是这个函数的地址,所以你这个程序相当于
  1. for i in range(k):
  2.     id(5)
复制代码

这样子写是不会报错的。
运行倒是能正常运行,可是根本就没进行什么打印或计算,,连赋值这种操作都没有,而且那个函数也根本没运行,所以就没耗费什么时间,趋近于0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-21 15:46:46 | 显示全部楼层
本帖最后由 °蓝鲤歌蓝 于 2020-2-21 15:51 编辑
Kituro_ 发表于 2020-2-21 15:30
复用性太低是指代码不够简洁吗


是的,比如
  1. def start(self):
  2.         if self.mode == 1:
  3.             self.strat_time = time.perf_counter()
  4.             print("计时开始!")
  5.         if self.mode == 2:
  6.             self.start_time = time.process_time()
  7.             print("计时开始!")

  8.     def stop(self):
  9.         if self.mode == 1:
  10.             self.end_time = time.perf_counter()
  11.             self.workingTime = self.end_time - self.start_time
  12.             print("计时结束!")
  13.             print("计时器运行了%f秒"%(self.workingTime))
  14.         if self.mode == 2:
  15.             self.end_time = time.process_time()
  16.             self.workingTime = self.end_time - self.start_time
  17.             print("计时结束!")
  18.             print("计时器运行了%f秒"%(self.workingTime))
复制代码


这两个函数的内部代码几乎完全一样,不需要写成两个函数,而且就单个stop函数而言,内部实现也不够简洁,完全可以写成下面那样

  1.     def stop(self):
  2.         if self.mode == 1:
  3.             self.end_time = time.perf_counter()
  4.         if self.mode == 2:
  5.             self.end_time = time.process_time()
  6.         self.workingTime = self.end_time - self.start_time
  7.         print("计时结束!")
  8.         print(f"计时器运行了{self.workingTime}秒"
复制代码

甚至在不考虑传入的数字会是 1,2 以外的情况下,还可以这样写

  1.     def stop(self):   
  2.         self.end_time = time.perf_counter() if self.mode == 1 else time.process_time()
  3.         self.workingTime = self.end_time - self.start_time
  4.         print("计时结束!")
  5.         print(f"计时器运行了{self.workingTime}秒")
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-21 15:49:50 | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-2-21 15:46
是的,比如

这两个函数的内部代码几乎完全一样,不需要写成两个函数,而且就单个stop函数而言,内部实 ...

非常感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-2-16 15:22:00 | 显示全部楼层
可是这个process_time()穿的结果不太对把(times=300 结果小于 times =100),process_time()的调用貌似直接返回时间段结果的(和perf_counter随机选取时间点貌似不太一样).
所以process_time()到底怎么用啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-18 21:36

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表