如何在Python中交互式(微)基准测试代码表达式(即相当于Julia中的@btime
/@benchmark
) ?
我想交互式地对一个表达式(一个函数调用)进行基准测试,其中该表达式应该评估的次数取决于其计算成本/方差....
我试过timeit.timeit
,但我有一些问题:
- 如何解释以下结果的时间输出:
>>> a = 2.2
>>> timeit.repeat("round(a)", setup='from __main__ import a; gc.enable()', repeat=5,number=10)
[4.631001502275467e-06, 1.3809185475111008e-06, 1.2170057743787766e-06, 1.1718366295099258e-06, 1.1730007827281952e-06]
>>> timeit.timeit("round(a)", setup='from __main__ import a; gc.enable()', number=10)
5.741836503148079e-06
>>> timeit.timeit("round(a)", setup='from __main__ import a; gc.enable()')
0.11461802502162755
>>> timeit.Timer('round(a)', setup='from __main__ import a; gc.enable()').autorange()
(5000000, 0.4272152939811349)
当我从number
从1
到10
时,时间似乎保持相当稳定,但随后它增长了不同的数量级....
- 是否有意义的工作流程,我首先创建
Timer
对象一次,然后我修改几次代码来评估和基准测试修改的计时器?例如
import timeit
import gc
bclass = timeit.Timer('round(1.1)','gc.enable()', globals=globals())
[...]
bclass.stmt = "small_3x2_nash.vertex_enumeration()"
bclass.autorange()
bclass.stmt = "small_3x2_nash.lemke_howson_enumeration()"
bclass.autorange()
bclass.stmt = "small_3x2_nash.support_enumeration()"
bclass.autorange()
(似乎这是不可能的,因为我已经尝试了非常不同的代码和计时的结果仍然几乎相同)
您也可以使用Timer类来启用de GC,如这里的文档所述:https://docs.python.org/3/library/timeit.html#timeit.Timer.timeit
而不是显式地从main导入你想要使用的每个变量/函数,您可以在Timer参数中传递globals()
。这样,所有的全局变量、函数等都将被传递给解值函数。
Python 3.10.10 (main, Mar 5 2023, 22:26:53) [GCC 12.2.1 20230201] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>>
>>> a = 2.2
>>>
>>> t = timeit.Timer('round(a)', globals=globals())
>>>
>>> t.timeit(number=1000)
0.00042562399994494626
>>> t.autorange()
(5000000, 0.46861540100007915)
要启用GC,还需要导入gc
库
import gc
t = timeit.Timer('round(a)', 'gc.enable()', globals=globals())