小智..
5
我会翻转这个问题:不要在一秒钟内将循环限制为N次.相反,处理N个工作单元在所需时间内均匀分布.
也就是说,计算出有多少时间已经过去了,因为在开始(或以前的工作),插即进入工作速度,并做大量的工作(因素,在开始/先前的时间和已完成的工作量).这是许多游戏/动画引擎的基本支撑 - 一个"增量时间".
然后yield在每个循环结束时调用"很好" - 或者更确切地说,防止吃掉99%以上的CPU用量!屈服本身具有最小分辨率1,但效果通常是足够的,特别是在适当插值时.
因为使用了插值方法,所以这应该适用于所有N(可以在分配的时间内运行),即使这意味着每个循环执行更多N. 也可能没有任何工作可以为小N做任何特定的循环,但这yield使得这种"额外繁忙的循环"在CPU利用率方面便宜2.
这里有一些伪代码可以在一秒内打印出20"x"s,其中now返回小数秒:
rate = 20 // per second - "N times per second"
done = 0
goal = 1 * rate // same as rate for 1 second
start = now()
while done < goal:
target = floor((now() - start) * rate)
work = (target - done) // work might be 0, that's okay
for 0 upto work:
print("x")
done += work
yield()
在这种情况下,由于恒定速率公式,很容易插入开始时间.使用自上次工作(或环)的关断时的"Δ时间"是类似的,并且适合当没有离散的公式,但稍微复杂,并可能导致微妙漂移误差.
1实际 的时间分辨率sleep/yield取决于实现,因系统而异.例如,它可能从Linux上的1毫秒到Windows上的10-15毫秒.
2在除了处理一个时间差,该sleep时间段可以改变,按了Dariusz Wawer的答案.然而,这增加了复杂性并且yield通常足够简单.