【问题标题】:How can I measure thread specific time in Android?如何在 Android 中测量线程特定时间?
【发布时间】:2017-12-01 01:16:56
【问题描述】:

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

ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();

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

【问题讨论】:

  • 定义CPU时间。您是否需要 CPU 启动后的时间、经过的时间、挂墙时间或其他时间?您还需要什么级别的精度?
  • 此外,即使在标准 java 下也没有承诺支持 currentThreadCpuTime。
  • 我想在 Android 中分析一个方法的运行时间。如果我用System.nanoTime() 测量时间(例如,t1=System.nanoTime(); methodCall(); timeDiff = System.nanoTime() - t1;),其他计时测量(例如,上下文切换时间,其他线程运行时间) 将包含在计算的时间差中。所以,我只想计算这个特定线程的执行时间。据我所知,在标准 Java 中,我们可以使用“getCurrentThreadCpuTime()”。但是,我不知道如何在 Android 中做到这一点。

标签: java android benchmarking cpu-time


【解决方案1】:

我不熟悉 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 */ }

【讨论】:

    【解决方案2】:

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

    SystemClock.currentThreadTimeMillis(); 
    

    Android documentation 声明此方法

    返回在当前线程中运行的毫秒数。

    【讨论】:

      【解决方案3】:

      CPU 时间方法

      SystemClock.currentThreadTimeMillis:

      implementation 可以看到它使用CLOCK_THREAD_CPUTIME_ID,并将纳米除以毫。同样有currentThreadTimeMicro。 这两个使用@CriticalNative注解,甚至比@FastNative还要快。这种特殊的优化要求方法不使用对象,只使用原语,并且是静态的。因此,根本没有使用JNIEnv。与@FastNative类似,这些注解仅用于平台调用,并非动态链接,而是由框架事先专门链接。

      android.os.Debug.threadCpuTimeNanos()

      获取线程 CPU 使用率的指示。返回的值表示 当前线程执行代码所花费的时间或 等待某些类型的 I/O。 时间以纳秒表示,仅在以下情况下才有意义 与之前调用的结果相比。请注意,纳秒 分辨率并不意味着纳秒级精度。

      通过检查 Android 运行时 (ART),这将调用 ThreadCpuNanoTime 方法,该方法使用 CLOCK_THREAD_CPUTIME_ID。此外,它被标记为fast Native method,并在Java 中注释为@FastNative。这允许通过加速 JNI 转换来优化它。我猜这个优化,类似于@CriticalNative,利用了他们不需要完全构造/破坏JNI环境的事实,因为这里没有真正的依赖关系。它本质上只是一个syscall

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

      挂钟接近

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

      【讨论】:

        猜你喜欢
        • 2017-12-08
        • 1970-01-01
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-16
        相关资源
        最近更新 更多