首页 > 解决方案 > time.time() 在 Cython 中无法在预定时间内运行 while 循环

问题描述

我有一个 Python 模块,其中包含一个应该运行固定时间的 while 循环。我通过在 time.time() 的输出中添加一个常量并运行直到 time.time() 大于该变量来做到这一点。这没有出现任何问题,但同样的事情在 Cython 中对我不起作用。现在我正在疯狂地偏离时间。

仅举一个证明这一点的最小示例:

import time

cdef float wait_time = 3

def slow():
    cdef float end_time = time.time() + wait_time

    while time.time() < end_time:
        pass
    print("Done")
%timeit -r1 -n1 slow()
Done
44.2 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
35.5 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
35.5 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
19.5 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
35.5 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
20.6 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
20 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
56 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
1min 3s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
32.9 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

%timeit -r1 -n1 slow()
Done
1min 5s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)

这往往遵循的一般行为是基本上没有等待,除非在运行函数之前暂停一段时间,在这种情况下会有过度等待。

标签: pythoncython

解决方案


Pythonfloat是 C 的double。Cfloat 通常只有 24 个有效位(其中一个是隐含的),使其精度为 128 秒(自 2004 年以来)。当您的加法从向下舍入变为向上舍入时,它会从过去一分钟移动到未来一分钟的值。


推荐阅读