gpt4 book ai didi

java - 是否有可能使这个 Java 计时器具有优于 ~15 ms 的分辨率?

转载 作者:行者123 更新时间:2023-11-30 09:04:14 27 4
gpt4 key购买 nike

我用 Java 构建了一个计时循环。简单的。我正在避免使用 Thread.sleep(),因为我的线程调度开销使高分辨率延迟变得不可能,因此我使用了以下非常低效的循环并获得了更好的结果:

public static void timerBlockingDelayTest()
{
long DELAY_TARGET = 5;
long t0, t;

t0 = System.currentTimeMillis();
while (System.currentTimeMillis() < t0+DELAY_TARGET) {}
t = System.currentTimeMillis();

long offTargetAmt = Math.abs(t-t0-DELAY_TARGET);
System.out.format("Timer loop was off target by %d milliseconds\n",
offTargetAmt);
}

我所知道的事情:操作系统不是实时的,线程调度是操作系统随心所欲,GC 会导致延迟。

我没有考虑到什么?

在我的机器(Windows 7 x64、i5、2.4GHz)上,我可以获得的最佳分辨率约为 15 毫秒。事实上,如果我将 DELAY_TARGET 设置为 15 的倍数,效果会很好。但是,如果目标时间不接近 15 的倍数,则上面的 offTargetAmt 将定期为 ~8 (ms)。

我也知道这篇文章:high resolution timer in java

这到底是怎么回事?!正负 ~8 毫秒真的是我能做的最好的吗??!我只是在寻找“是的,没错”或“不,你没有考虑过___”的答案。谢谢

更新:

使用 System.nanoTime() 似乎有很大的不同。起初我不相信,但这是我比较这两种方法的更新代码。你自己看。

public static void timerBlockingDelayTest()
{
long DELAY_TARGET_MS = 5;
long NS_PER_MS = 1000000;
long DELAY_TARGET_NS = DELAY_TARGET_MS * NS_PER_MS;
long t0, t;

// Using System.currentTimeMillis()
t0 = System.currentTimeMillis();
while (System.currentTimeMillis() < t0+DELAY_TARGET_MS) {}
t = System.currentTimeMillis();
long msOffTarget = Math.abs(t-t0-DELAY_TARGET_MS);

// Using System.nanoTime()
t0 = System.nanoTime();
while (System.nanoTime() < t0+DELAY_TARGET_NS) {};
t = System.nanoTime();
long nsOffTarget = Math.abs(t-t0-DELAY_TARGET_NS);

// Compare the two methods
System.out.format("System.currentTimeMillis() method: ");
System.out.format(" - Off by %d ms (%d ns) \n",
msOffTarget, msOffTarget*NS_PER_MS);
System.out.format("System.nanoTime() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget/NS_PER_MS, nsOffTarget);
}

这是一个示例输出:

debug:
System.currentTimeMillis() method: - Off by 11 ms (11000000 ns)
System.nanoTime() method: - Off by 0 ms (109 ns)
BUILD SUCCESSFUL (total time: 0 seconds)

更新 2(希望是最后一次):

呃。 单独测量量化或不完美时间函数的性能有点愚蠢。我的意思是我实际上是在测量 currentTimeMillis() 本身的性能,这不是我做过的最聪明的事情。意识到这一点后,我对上述两种方法进行了分析,发现确实 nanoTime() 产生了更好的分辨率。

如果您没有分析器,请使用 nanoTime() 来测量 currentTimeMillis() 循环的持续时间,如下所示:

public static void timerBlockingDelayTest()
{
long DELAY_TARGET_MS = 5;
long NS_PER_MS = 1000000;
long DELAY_TARGET_NS = DELAY_TARGET_MS * NS_PER_MS;
long t0ms, t0, t;

// Using System.currentTimeMillis()
t0 = System.nanoTime();
t0ms = System.currentTimeMillis();
while (System.currentTimeMillis() < t0ms+DELAY_TARGET_MS) {}
t = System.nanoTime();
long nsOffTarget1 = Math.abs(t-t0-DELAY_TARGET_NS);

// Using System.nanoTime()
t0 = System.nanoTime();
while (System.nanoTime() < t0+DELAY_TARGET_NS) {};
t = System.nanoTime();
long nsOffTarget2 = Math.abs(t-t0-DELAY_TARGET_NS);

// Compare the two methods
System.out.format("System.currentTimeMillis() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget1/NS_PER_MS, nsOffTarget1);
System.out.format("System.nanoTime() method: ");
System.out.format(" - Off by %d ms (%d ns)\n",
nsOffTarget2/NS_PER_MS, nsOffTarget2);
}

至少我通过相同的引用来测量两个延迟,这只是稍微更智能一点。上面给出了这样的输出:

debug:
System.currentTimeMillis() method: - Off by 4 ms (4040402 ns)
System.nanoTime() method: - Off by 0 ms (110 ns)
BUILD SUCCESSFUL (total time: 0 seconds)

结论:使用 nanoTime(),祝你有美好的一天。

最佳答案

使用System.nanoTime反而。参见 this answer关于 nanoTime 和 currentTimeMillis 的区别。

关于java - 是否有可能使这个 Java 计时器具有优于 ~15 ms 的分辨率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25342872/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com