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

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

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

当我运行我的测验应用程序并首次回答问题时,主UI线程将冻结,因为它执行计算,但所有后续计算将非常快。 下面,我列出了一系列我为了解决问题而尝试的策略。 注:我已经注入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:在启动画面中运行一个新的线程活动结果:这解决了启动画面加载太长的问题,但如果我在主线程上回答一个问题,并在其他线程的初始计算完成之前检查它的正确性,UI线程冻结。


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

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

我仍然得到一个缓慢的初始计算,所有的后续调用都是闪电般的。 我不知道这里发生了什么,我想知道是否是一个本机android问题,其中重计算需要执行至少一次所有后续的计算是平稳的。

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