我正在试图计算我的程序的FPS。虽然给定的最大FPS是超限,但我无法解释原因。我用MAX_FPS设置为60对它进行了测试,我总是得到关于63显示的信息。
{...}
int frameCount = 0;
long time = System.currentTimeMillis();
while(running) {
try {
{...} // do something
Thread.sleep(1000 / MAX_FPS);
frameCount++;
if (System.currentTimeMillis() - time >= 1000) {
{...} // display FPS w/ frameCount
frameCount = 0;
time = System.currentTimeMillis();
}
} catch (InterruptedException ex) {
System.err.println(ex.toString());
}
}
{...}发布于 2015-02-10 00:02:33
根据NESPowerGlove的答案,达到目标FPS的问题是,您必须选择一个整数值来调用Thread.sleep() --如果您选择16,您将得到大约63 FPS;如果您选择17,您将得到大约58 FPS。
对此,我可以想到两种解决方案:
0.55值和0.14值均经反复试验确定.更好的值可能是可用的(但至少它似乎大致稳定)。fps产出:
61.08042479827653
61.817816897275485
58.42717726642977
62.0654826347193
58.43759367657694
62.07263954479402
58.444556146850026
62.05489635777375
58.4438970272065
62.05784933619571
58.45590905841833
62.069491426232766
58.44381852435569
62.07438904528996
...实际上,积分项没有多大作用--大概是因为睡眠值只能在大小为1的步骤中变化。
System.nanoTime(),直到超过某个截止日期。例如:
long time = System.nanoTime();for (int frameCount = 0;true;++frameCount) { long end = System.nanoTime() + ( long ) (1_000_000_000.0 / TARGET_FPS);while (System.nanoTime() < end);long time= System.nanoTime() - time;if ( frameCount >= 1_000_000_000) { double fps = (double) frameCount / elapsed * 1e9;System.out.println(fps);frameCount= 0;时间= System.nanoTime();}这似乎是更好的工作,FPS徘徊在60以下:
58.99961555850502
59.99966304189236
59.99942898543434
59.99968068169941
59.99968770162551
59.99919595077507
59.99945862488483
59.999679241714766
59.99753134157542
59.99963898217224
59.999265728986
...这样做的缺点可能是while循环会很热。
当然,您可以采用某种混合方法,在大部分等待时间使用Thread.sleep,然后使用热while循环来获得更精确的延迟。
发布于 2015-02-09 22:59:49
1000 / 60在整数数学中是16,1000 / 16大约是62.5。假设线程确实睡了将近16毫秒(也许更少一点),如果你的循环没有花那么长时间执行一次迭代,如果到最后一个帧的第二个时间是999毫秒,允许另一个更新溜进来,那么循环每秒可以完成63次迭代是有意义的。
发布于 2015-02-09 23:11:07
您可能需要使用System.nanoTime()代替。不是为了任何额外的精度,而是因为它是一种更正确的方法来测量经过的时间。参见Kevin对How do I measure time elapsed in Java?的回答。
https://stackoverflow.com/questions/28421016
复制相似问题