鱼C论坛

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

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

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

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

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

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

                               
登录/注册后可看大图


这里使用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作为计时模式时输出如下:

                               
登录/注册后可看大图

最佳答案
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。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

还有
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 是一个函数签名,也就是这个函数的地址,所以你这个程序相当于
for i in range(k):
    id(5)
这样子写是不会报错的。
运行倒是能正常运行,可是根本就没进行什么打印或计算,,连赋值这种操作都没有,而且那个函数也根本没运行,所以就没耗费什么时间,趋近于0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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}秒")
想知道小甲鱼最近在做啥?请访问 -> 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-6-9 18:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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