欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中各種Time API詳細(xì)

 更新時間:2021年10月14日 14:41:17   作者:貓尾巴  
這篇文章要分享的是Android中各種Time API, SystemClock.uptimeMillis()、System.nanoTime(),下面我們就來看看他們到底有什么區(qū)別吧

1、時間API

為了跟蹤性能,我們需要測量時間間隔,即兩個時間點之間的差異。 JDK 為我們提供了兩種獲取當(dāng)前時間的方法:

// Milliseconds since Unix epoch (00:00:00 UTC on 1 January 1970)
System.currentTimeMillis()
// Nanoseconds since the VM started.
System.nanoTime()

Android 提供了一個 SystemClock 類,它增加了一些:

// (API 29) Clock that starts at Unix epoch.
// Synchronized using the device's location provider.
SystemClock.currentGnssTimeClock()
// Milliseconds running in the current thread.
SystemClock.currentThreadTimeMillis()
// Milliseconds since boot, including time spent in sleep.
SystemClock.elapsedRealtime()
// Nanoseconds since boot, including time spent in sleep.
SystemClock.elapsedRealtimeNanos()
// Milliseconds since boot, not counting time spent in deep sleep.
SystemClock.uptimeMillis()

我們應(yīng)該選擇哪一個? SystemClock javadoc 有助于回答這個問題:

System#currentTimeMillis 可以由用戶或電話網(wǎng)絡(luò)設(shè)置,因此時間可能會不可預(yù)測地向后或向前跳躍。 間隔或經(jīng)過時間測量應(yīng)使用不同的時鐘。

SystemClock#uptimeMillis 在系統(tǒng)進(jìn)入深度睡眠時停止。 這是大多數(shù)間隔計時的基礎(chǔ),例如 Thread#sleep(long) 、Object#wait(long) System#nanoTime。 當(dāng)間隔不跨越設(shè)備休眠時,該時鐘適用于間隔計時。

SystemClock#elapsedRealtime SystemClock#elapsedRealtimeNanos 包括深度睡眠。 該時鐘是通用間隔計時的推薦基礎(chǔ)。

應(yīng)用程序的性能對深度睡眠中發(fā)生的事情沒有影響,所以我們最好的選擇是 SystemClock.uptimeMillis() System.nanoTime()

2、uptimeMillis() vs nanoTime()

System.nanoTime() uptimeMillis() 更精確,但這僅對微基準(zhǔn)測試有用。 在生產(chǎn)中跟蹤性能時,我們需要毫秒級的分辨率。

讓我們比較一下它們的性能影響。 我克隆了 Android Benchmark Samples 存儲庫并添加了以下測試:

@LargeTest
@RunWith(AndroidJUnit4::class)
class TimingBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()

    @Test
    fun nanoTime() {
        benchmarkRule.measureRepeated {
            System.nanoTime()
        }
    }

    @Test
    fun uptimeMillis() {
        benchmarkRule.measureRepeated {
            SystemClock.uptimeMillis()
        }
    }
}

在運行 Android 10 的 Pixel 3 上的結(jié)果:

System.nanoTime() 中值時間:208 ns

SystemClock.uptimeMillis() 中值時間:116 ns

SystemClock.uptimeMillis() 幾乎快兩倍! 雖然這種差異應(yīng)該不會對應(yīng)用程序產(chǎn)生任何有意義的影響,但我們能弄清楚為什么它要快得多嗎?

3、uptimeMillis() 實現(xiàn)

SystemClock.uptimeMillis() 實現(xiàn)為帶有@CriticalNative 注釋的本機(jī)方法。 CriticalNative 為不包含對象的方法提供更快的 JNI 轉(zhuǎn)換。

public final class SystemClock {
    @CriticalNative
    native public static long uptimeMillis();
}

原生實現(xiàn)在 SystemClock.c++ 中:

int64_t uptimeMillis()
{
    int64_t when = systemTime(SYSTEM_TIME_MONOTONIC);
    return (int64_t) nanoseconds_to_milliseconds(when);
}

systemTime() 在 Timers.cpp 中定義:

nsecs_t systemTime(int clock) {
    static constexpr clockid_t clocks[] = {
        CLOCK_REALTIME,
        CLOCK_MONOTONIC,
        CLOCK_PROCESS_CPUTIME_ID,
        CLOCK_THREAD_CPUTIME_ID,
        CLOCK_BOOTTIME
    };
    timespec t = {};
    clock_gettime(clocks[clock], &t);
    return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec;
}

4、nanoTime() 實現(xiàn)

System.nanoTime() 也被實現(xiàn)為帶有@CriticalNative 注釋的本地方法。

public final class System {
    @CriticalNative
    public static native long nanoTime();
}

本地實現(xiàn)在 System.c 中:

static jlong System_nanoTime() {
  struct timespec now;
  clock_gettime(CLOCK_MONOTONIC, &now);
  return now.tv_sec * 1000000000LL + now.tv_nsec;
}

這兩個實現(xiàn)其實很相似,都調(diào)用clock_gettime()

事實證明,@CriticalNative 最近才被添加到 System.nanoTime() ,這就解釋了為什么它變慢了!

結(jié)論:

在生產(chǎn)應(yīng)用中跟蹤性能時:

對于大多數(shù)用例,毫秒分辨率就足夠了。 要測量時間間隔,請使用 SystemClock.uptimeMillis() System.nanoTime() 。 后者在較舊的 Android 版本上速度較慢,但這在這里無關(guān)緊要。

到此這篇關(guān)于Android中各種Time API詳細(xì)的文章就介紹到這了,更多相關(guān)Android中各種Time API內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論