【问题标题】:Why is the first computation in my Android app slow while all subsequent computations are fast为什么我的 Android 应用程序中的第一次计算很慢,而所有后续计算都很快
【发布时间】:2017-11-27 08:53:57
【问题描述】:

我正在使用 symja android 库为我正在构建的测验应用程序执行数学计算。我的所有计算都是通过将诸如“1+3 + (4/2)”之类的字符串传递给库中名为 ExprEvaluator() 的类来执行的。示例用法是

ExprEvaluator().evaluate("1+3 + (4/2)") //Kotlin 

当我第一次运行我的测验应用并回答问题时,主 UI 线程会在执行计算时冻结,但所有后续计算都会非常快。下面,我概述了我为解决问题而尝试的一系列策略。注意:我已经用 Dagger 注入了 ExprEvaluator 类,它作为一个单例存在

class ChallengeUtils {

@Inject lateinit var exprEvaluator: ExprEvaluator
...
fun evaluate(expression: String?): IExpr? {
    try {
        return exprEvaluator.evaluate(expression)
    } catch (e: Exception) {
        throw (e)
    }
}

策略 1:将计算卸载到单独的线程 结果:初始计算时间没有影响,实际上导致了更多问题,因为我需要主 UI 线程上的结果。所有后续计算都像往常一样快速。

策略 2:在我的 SplashScreen Activity 上运行一个简单的初始计算。 结果:这是我找到的最好的解决方案,但唯一的缺点是我的启动画面花费的时间太长。进入主应用程序后,测验的表现非常好。

策略 3:在启动画面活动内的新线程上运行 结果:这解决了启动画面加载时间过长的问题,但是如果我在主线程上回答问题并在其他线程的初始计算完成之前检查它的正确性,UI 线程就会冻结。


我注意到,无论我传入什么字符串,第一次调用评估总是很慢。我可以传入“1”,评估大约需要 4 秒,而所有后续更复杂的评估最多需要几毫秒。即使我使用 ExprEvaluator 类的新实例来进行每个 sinccle 计算,如下所示:

fun evaluate(expression: String?): IExpr? {
try {
    return ExprEvaluator().evaluate(expression)
} catch (e: Exception) {
    throw (e)
}

我的初始计算仍然很慢,并且所有后续的评估调用都快如闪电。我不太确定这里发生了什么,我想知道这是否是原生 android 问题,需要至少执行一次繁重的计算才能使所有后续计算顺利进行。

【问题讨论】:

  • 使用 systrace/内存转储查找可能的泄漏或其他情况

标签: android multithreading performance kotlin


【解决方案1】:
  1. 使用分析器来衡量方法所花费的时间,这是一个非常有用的工具!
  2. 类在第一次被引用时被加载到运行时,很可能ExprEvaluator构造函数或其方法正在引用库中的大量内部类,这些类都在第一次调用时加载,但对于所有后续调用,类已经加载到内存中。
  3. 尝试浏览库的反编译代码(只需Ctrl+B 或您为Go To -> Implementation 提供的任何快捷方式),或者如果您有原始源代码。它可以帮助您了解内部发生的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 2011-02-07
    • 2011-03-23
    • 2023-04-04
    • 1970-01-01
    • 2014-01-03
    • 2020-04-05
    相关资源
    最近更新 更多