我想以特定频率激发事件,例如44100hz
我希望下面的代码每秒执行44100次"打印",但事实并非如此。
import time
frequency = 44100
desired_interval = 1 / frequency
events = 0
time_now = time.time()
time_end = time_now +1
while time_now < time_end:
events += 1
print(events)
# some time has passed, sleep for desired interval less passed time
if( desired_interval > ( time.time() - time_now ) ):
time.sleep( desired_interval - ( time.time() - time_now ) )
time_now = time.time()
这更接近,即使很可能(非常确定(事件"print"不是以常规频率触发的。
import time
frequency = 44100
desired_interval = 1 / frequency
events = 0
time_now = time.time()
time_start = time_now
time_end = time_now +1
while time_now < time_end:
events += 1
print(events)
if( desired_interval * events > ( time.time() - time_start ) ):
# abs mitigate the fact that sometime the result is negative.
time.sleep( abs( desired_interval * events - ( time.time() - time_start ) ) )
time_now = time.time()
要了解为什么事情花费的时间比您想象的要长,我们必须使用探查器。
将您的代码保存为timer.py
后,我运行了以下操作;
python3 -m cProfile -s tottime timer.py
结果是:
37621
37622
37623
37624
37625
37626
188134 function calls in 1.000 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
37626 0.840 0.000 0.840 0.000 {built-in method time.sleep}
37626 0.104 0.000 0.104 0.000 {built-in method builtins.print}
1 0.045 0.045 1.000 1.000 timer.py:1(<module>)
112879 0.012 0.000 0.012 0.000 {built-in method time.time}
1 0.000 0.000 1.000 1.000 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
所以,在我的机器上,它每秒运行37626次。大部分时间都花在了运行time.sleep()
上。
问题是,在计算延迟时,您没有考虑python代码运行所需的时间。它也没有考虑到Python是在运行其他程序的操作系统之上运行的。
让我们将程序简化为:
import time
frequency = 44100
desired_interval = 1 / frequency * 0.72
events = 0
time_now = time.time()
time_end = time_now + 1
while time_now < time_end:
events += 1
print(events)
time.sleep(desired_interval)
time_now = time.time()
在我的系统上,它每秒打印大约44100次。正如你所看到的,考虑到开销,我不得不将睡眠时间减少约30%。这只是一个玩具程序。
从所需的频率来看,您似乎想要实时进行CD质量的音频处理。老实说,Python可能不是正确的选择。
您应该做的是将想要完成的实际工作封装在一个函数中,并在此函数上运行探查器。评测的结果将告诉您是否可以在所需的时间内完成所需的工作。
如果你做不到,有一些选择可以加快速度;
- 使用
numpy
- 使用
cython
- 使用
pypy