我正在撰寫一個涉及呼叫者定義的時間解析度的庫。在實作中,這個值最終是一些后臺執行緒在進行一些內務處理并再次進入睡眠之前將睡眠的時間間隔。我允許此解析度小至 1 毫秒,轉換為Thread.sleep(1). 我的直覺是,這可能比忙著等待 1 毫秒更浪費,也更不精確。如果是這樣的話;
- 我應該回到忙于等待足夠小(多小)的時間間隔嗎?
- 有誰知道 JVM 是否已經在做這個優化,而我根本不需要做任何事情?
uj5u.com熱心網友回復:
這很容易測驗:
public class Test {
static int i = 0;
static long[] measurements = new long[0x100];
static void report(long value) {
measurements[i & 0xff] = value;
if (i > 10_000) {
for (long m : measurements) {
System.out.println(m);
}
System.exit(0);
}
}
static void sleepyWait() throws Exception {
while (true) {
long before = System.nanoTime();
Thread.sleep(1);
long now = System.nanoTime();
report(now - before);
}
}
static void busyWait() {
while (true) {
long before = System.nanoTime();
long now;
do {
now = System.nanoTime();
} while (before 1_000_000 >= now);
report(now - before);
}
}
public static void main(String[] args) throws Exception {
busyWait();
}
}
在我的windows系統上運行,這說明busyWait有微秒級的精度,但是完全使用了一個CPU核。
相比之下, sleepyWait 不會導致可測量的 CPU 負載,但只能達到毫秒精度(通常需要 2 毫秒才能觸發,而不是請求的 1 毫秒)。
至少在 Windows 上,這是準確度和 CPU 使用率之間的直接權衡。
還值得注意的是,通常有其他方法可以替代全速運行 CPU 并癡迷地檢查時間。在許多情況下,您可能會等待其他一些信號,并且提供專注于基于時間的解決方案的 API 可能會將您的 API 用戶引向錯誤的方向。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459754.html
上一篇:Scala:遞回和堆疊溢位錯誤
