我的函数消耗了负时间。到底发生了什么?

3 投票
3 回答
2473 浏览
提问于 2025-04-16 01:35

我提出这个问题主要是出于好奇。我写了一些代码,做了一些非常耗时的工作。所以,在执行我的主要功能之前,我用几次调用 time.clock() 把它包裹起来。看起来像这样:

t1 = time.clock()
print this_function_takes_forever(how_long_parameter = 20)
t2 = time.clock()
print t2 - t1

这样做效果很好。我的函数返回结果正确,t2 - t1 给了我一个结果 972.29,大约是16分钟。

但是,当我把代码改成这样的时候:

t1 = time.clock()
print this_function_takes_forever(how_long_parameter = 80)
t2 = time.clock()
print t2 - t1

我的函数依然返回正常,但 t2 - t1 的结果却是:

None
-1741

我很好奇是什么实现细节导致了这种情况。None 和负数都让我感到困惑。这和有符号类型有关吗?这又是怎么解释 None 的呢?

3 个回答

1

关于None的情况,答案其实很简单,你的函数没有返回任何值。实际上,我觉得在正常情况下它是会返回值的,但当你传入的参数how_long_parameter等于80时,它似乎就提前结束了。可能是因为函数执行到最后时,Python会隐含地返回None,所以你看到的负时间可能是因为在这种情况下,函数几乎没有花费时间就完成了?所以你需要检查一下你的函数,找出问题并修正它。

至于为什么你会得到负时间,这实际上和你使用的操作系统有关,因为clock()在不同的平台上实现方式不同。在Windows上,它使用QueryPerformanceCounter(),而在*unix系统上,它使用C语言的clock()函数。

2

我来猜一下……看起来像是溢出问题。默认的数据类型可能是带符号的数据类型(在带符号整数中,把第一个位设置为1就会变成负数)。

你可以试着把减法的结果放到一个变量里(用双精度类型),然后再打印这个变量。

如果打印出来还是那样,你可以试着把它从双精度转换成字符串,然后再用'print'函数打印这个字符串。

17

Python的官方文档上说:

在Unix系统上,这个函数会返回当前的处理器时间,结果是一个以秒为单位的浮点数。这个时间的精确度,以及“处理器时间”这个概念的具体含义,实际上是依赖于一个同名的C语言函数。

而这个C语言函数的手册中进一步解释了这个问题:

请注意,时间可能会回绕。在一个32位系统上,如果CLOCKS_PER_SEC等于1000000,这个函数大约每72分钟会返回相同的值。

撰写回答