一个 Python 计时器封装的问题

2021-03-31 11:51:58 +08:00
 LeeReamond

日常编程中,常常纠结于哪种实现方式运行速度更快,需要对一些简短的 codeblock 进行测试

python 虽然有一个成熟的 timeit 生态,但是 timeit 的缺点是提供测试结果比较严谨,准备测试环境相对来说复杂一些。而这类日常的测试则不需要严谨的对比,通常只需要定性,哪个大略上更快一些,但是希望更加易用,写一行代码立即跑出结果,所以 timeit 并不是十分符合需求。

所以实际开发中通常倾向于手写一些小工具来实现计时,一般思路是使用上下文管理器,在进入和退出指定 block 的时候统计运行时间即可,并且这种做法不会形成单独 scope,不影响上下文数据结构。

现在有一个问题就是,通常性能对比需要循环执行才能看出差异,所以要写很多多余代码,比如

with timeit():
    for _ in range(1e8):
        ... # 真正需要测试的代码段

感觉每次都要重复写一个 for 循环挺麻烦的,有没有办法把这部分逻辑封装在对象里呢?

让使用上变成这种感觉

with timeit(1e8):
    ... # 需要测试的代码段

我是没什么思路,不知道怎么才能做到,有没有大佬分享一下想法

730 次点击
所在节点    问与答
8 条回复
liprais
2021-03-31 12:03:21 +08:00
装饰器啊
charexcalibur
2021-03-31 12:42:09 +08:00
装饰器
LeeReamond
2021-03-31 13:09:34 +08:00
@liprais
@charexcalibur

装饰器方案比现在更拉胯,比如我有一个简单的需求,我有某个列表,需要把里面内容全部+2,完全用原生实现我要考虑是循环速度快还是列表生成器速度快,像下面这两段代码

https://gist.github.com/GoodManWEN/23274b3bcdd6fbeb352bea9f44b85441

我用现在的方案,实现循环我需要多写一行 for _ in range(1e8):,如果用装饰器,还要多定义一个函数,并且引入一个新的 scope,语法没有变简洁,问题变多。
volvo007
2021-04-01 00:26:29 +08:00
@LeeReamond 装饰器,是的,即使看到了你的抱怨,还是装饰器
多写写习惯就好。话说回来,函数套函数怎么就难了
LeeReamond
2021-04-01 00:41:41 +08:00
@volvo007 显然套函数需要先定义,再调用,写两行代码多于原先一行代码,这是其一。同时函数引入新的 scope,单独测试段落引起上下文定义缺失问题,这是其二,以上两点是否很难理解?
xiaolinjia
2021-04-03 15:05:11 +08:00
@LeeReamond 之前用的 pysnooper 库有 with 块的实现,跟你的需求有点类似,或许可以看看源码改造下。
https://github.com/cool-RR/PySnooper
xiaolinjia
2021-04-03 21:32:00 +08:00
https://www.v2ex.com/t/766801#reply6 我简单得写了一个。
xiaolinjia
2021-04-03 21:32:37 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/766801

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX