如何在Python中对单个函数调用进行基准测试?

3
如何在Python中交互式地(微)基准测试代码表达式(即Julia中的@btime/@benchmark的等效物)?
我想要交互式地基准测试一个表达式(一个函数调用),其中这个表达式被评估的次数取决于它的计算成本/方差...
我尝试过timeit.timeit,但我有一些问题:
1. 如何解释以下结果的时间输出:
>>> 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)

当我从110遍历number时,时间似乎保持相对稳定,但是随后增长的数量级不同....

  1. 是否有意义创建一个工作流程,在其中首先创建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()

看起来这似乎不可能,因为我尝试了很多不同的代码,但计时结果几乎没有变化。

1个回答

3

您也可以使用Timer类启用GC,如文档中所述:https://docs.python.org/3/library/timeit.html#timeit.Timer.timeit

而且,您可以在计时器参数中传递globals(),而不是明确导入要从main中使用的每个变量/函数。以这种方式,所有全局变量、函数等都将传递给评估函数。

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())

非常感谢。我无法将两个东西结合在一起(全局变量和gc.enable())。另外,输出如何解释?我注意到当您将“number”从1移动到10或更多时的时间保持稳定,但然后增加。 - Antonello
编辑后,如果要使用gc,您还需要导入gc库。 - GaNiziolek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接