为什么我的Android应用中的第一个计算速度慢,而所有后续计算都很快

时间:2017-06-23 17:39:41

标签: android multithreading performance kotlin

我正在使用symja安卓库为我正在构建的测验应用程序执行数学计算。我的所有计算都是通过传入一个字符串来执行的,例如" 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活动上运行一个简单的初始计算。 结果:这是我发现的最佳解决方案,但唯一的缺点是我的启动画面耗时太长。进入主应用程序后,测验表现非常好。

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

我注意到第一次评估的调用总是很慢,无论我传入的字符串。我可以传入" 1"并且评估将花费大约4秒,而所有后续更复杂的评估最多需要几毫秒。即使我为每个sincle计算使用ExprEvaluator类的新实例,如下所示:

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

我仍然得到一个缓慢的初始计算,所有要评估的后续调用都是快速的。我不确定这里发生了什么,我想知道它是否是一个本机安卓问题,其中重度计算需要至少执行一次才能使所有后续计算顺利进行。

1 个答案:

答案 0 :(得分:1)

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