如何在 Android 中测量线程特定时间?

How can I measure thread specific time in Android?

在标准 JVM(例如 1.8 版)中,我们可以像这样访问当前线程的时间:

ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();

在 Android(即 Dalvik VM)中获取当前线程时间的等效方法是什么。

我不熟悉 Java API 中的任何此类等价物。

超越 Java API 的思考,但是...您能从 top 中收集到任何有用的信息吗?

top -t 显然会在报告中包含特定于线程的信息。这是 运行 在我的一台设备上的结果:

那里似乎有可用的线程和 CPU 利用率数据。

访问此输出将涉及一些原始形式的输入流处理,例如

try {
    final String cmd = "top -t"

    final Process ps = Runtime.getRuntime().exec(cmd);
    ps.waitFor();

    final InputStream instream = ps.getInputStream();

    ...

} catch(Throwable t) { /* handle errors */ }
} finally { /* clean-up */ }

所以,我在 Android 中找到了这个解决方案:

SystemClock.currentThreadTimeMillis(); 

Android documentation 声明此方法

Returns milliseconds running in the current thread.

CPU时间方法

SystemClock.currentThreadTimeMillis:

来自implementation you can see that it is using CLOCK_THREAD_CPUTIME_ID, and dividing nanos to millis. Similarly there is currentThreadTimeMicro。 这两个使用 @CriticalNative 注解,比 @FastNative 还要快。这种特殊的优化要求该方法不使用对象,只使用基元,并且是静态的。因此,根本没有使用 JNIEnv 。与@FastNative类似,这些注解仅供平台调用使用,不是动态链接的,而是框架事先专门链接的。

android.os.Debug.threadCpuTimeNanos()

Get an indication of thread CPU usage. The value returned indicates the amount of time that the current thread has spent executing code or waiting for certain types of I/O. The time is expressed in nanoseconds, and is only meaningful when compared to the result from an earlier call. Note that nanosecond resolution does not imply nanosecond accuracy.

通过检查 Android 运行时 (ART),这会调用 ThreadCpuNanoTime method, which uses the CLOCK_THREAD_CPUTIME_ID. Also, it is marked as a fast Native method and annotated in Java as @FastNative. This allows it to be optimized by speeding up the JNI transitions. I guess that this optimization, similarly to @CriticalNative, takes advantage of the fact that they do not need to fully construct/destruct a JNI environment, since there are no really dependencies here. It's essentially just a syscall

或者,可以实现一个 JNI 方法来做同样的事情,但不会有更快的 JNI 处理。

挂钟接近

System.nanoTime()currentTimeMillis()都没有绑定线程,使用CLOCK_MONOTONIC.