我想以某个频率触发事件,例如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()
要了解为什么花费比您认为更长的时间,我们必须使用profiler。
将您的代码另存为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
。