Kituro_ 发表于 2020-2-21 14:25:00

关于time模块的perf_counter与process_time

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

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

import time
class Timer:
    start_time = 0
    end_time = 0
    workingTime = 0
    mode = 1
    def __init__(self,func,times = 1):
      print("可以使用set_timer方法改变计时器的运行模式")
      print("传入1使用 perf_counter ,传入2使用 process_time")
      print("默认计时方式为 perf_counter")
      self.times = times
      self.func = func
    def __str__(self):
      return_str = "计时器运行了" + str(self.workingTime) + "秒"
      return return_str
    def __repr__(self):
      return_str = "计时器运行了" + str(self.workingTime) + "秒"
      return return_str
   
    def set_timer(self,mode):
      if mode == 1:
            self.mode == mode
            print("修改成功,计时模式为 perf_counter")
      if mode == 2:
            print("修改成功,计时模式为 process_time")
            self.mode == mode
   
    def start(self):
      if self.mode == 1:
            self.strat_time = time.perf_counter()
            print("计时开始!")
      if self.mode == 2:
            self.start_time = time.process_time()
            print("计时开始!")

    def stop(self):
      if self.mode == 1:
            self.end_time = time.perf_counter()
            self.workingTime = self.end_time - self.start_time
            print("计时结束!")
            print("计时器运行了%f秒"%(self.workingTime))
      if self.mode == 2:
            self.end_time = time.process_time()
            self.workingTime = self.end_time - self.start_time
            print("计时结束!")
            print("计时器运行了%f秒"%(self.workingTime))

    def timing(self):
      self.mode = 2
      self.start()
      for i in range(self.times):
            self.func
      self.stop()


def func1():
    print("Hello World")

t1 = Timer(func1,100)

t1.timing()

这里使用process_time作为计时模式时输出如下:
http://i2.tiimg.com/581655/c1ae76cb373ecd0b.jpg

°蓝鲤歌蓝 发表于 2020-2-21 15:17:01

第53行改成
self.func()

还有
t1 = Timer(func1,100)
第二个参数改大一点,改个1w-100w 之间吧,这样比较明显一些。

最后,你的程序复用性太低了,可以再简洁一点的。

Kituro_ 发表于 2020-2-21 15:29:02

°蓝鲤歌蓝 发表于 2020-2-21 15:17
第53行改成




好的谢谢呢,不过为什么在采用perf_counter进行计时的时候,第五十三行的self.func不加括号也可以正常运行呢?

Kituro_ 发表于 2020-2-21 15:30:00

°蓝鲤歌蓝 发表于 2020-2-21 15:17
第53行改成




复用性太低是指代码不够简洁吗

°蓝鲤歌蓝 发表于 2020-2-21 15:43:05

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

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

这样子写是不会报错的。
运行倒是能正常运行,可是根本就没进行什么打印或计算,,连赋值这种操作都没有,而且那个函数也根本没运行,所以就没耗费什么时间,趋近于0。

°蓝鲤歌蓝 发表于 2020-2-21 15:46:46

本帖最后由 °蓝鲤歌蓝 于 2020-2-21 15:51 编辑

Kituro_ 发表于 2020-2-21 15:30
复用性太低是指代码不够简洁吗

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

    def stop(self):
      if self.mode == 1:
            self.end_time = time.perf_counter()
            self.workingTime = self.end_time - self.start_time
            print("计时结束!")
            print("计时器运行了%f秒"%(self.workingTime))
      if self.mode == 2:
            self.end_time = time.process_time()
            self.workingTime = self.end_time - self.start_time
            print("计时结束!")
            print("计时器运行了%f秒"%(self.workingTime))


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

    def stop(self):
      if self.mode == 1:
            self.end_time = time.perf_counter()
      if self.mode == 2:
            self.end_time = time.process_time()
      self.workingTime = self.end_time - self.start_time
      print("计时结束!")
      print(f"计时器运行了{self.workingTime}秒"
甚至在不考虑传入的数字会是 1,2 以外的情况下,还可以这样写

    def stop(self):   
      self.end_time = time.perf_counter() if self.mode == 1 else time.process_time()
      self.workingTime = self.end_time - self.start_time
      print("计时结束!")
      print(f"计时器运行了{self.workingTime}秒")

Kituro_ 发表于 2020-2-21 15:49:50

°蓝鲤歌蓝 发表于 2020-2-21 15:46
是的,比如

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

非常感谢!

peipur 发表于 2021-2-16 15:22:00

可是这个process_time()穿的结果不太对把(times=300 结果小于 times =100),process_time()的调用貌似直接返回时间段结果的(和perf_counter随机选取时间点貌似不太一样).
所以process_time()到底怎么用啊
页: [1]
查看完整版本: 关于time模块的perf_counter与process_time