为什么我的Android应用程序中的第一次计算很慢,而随后的所有计算都很快
我正在使用symja android库为我正在构建的测验应用程序执行数学计算。我的所有计算都是通过将字符串(如“1+3+(4/2)”传递给库中名为exprewator()的类来执行的。示例用法如下:为什么我的Android应用程序中的第一次计算很慢,而随后的所有计算都很快,android,multithreading,performance,kotlin,Android,Multithreading,Performance,Kotlin,我正在使用symja android库为我正在构建的测验应用程序执行数学计算。我的所有计算都是通过将字符串(如“1+3+(4/2)”传递给库中名为exprewator()的类来执行的。示例用法如下: ExprEvaluator().evaluate("1+3 + (4/2)") //Kotlin 当我第一次运行测验应用程序并回答问题时,主UI线程在执行计算时会冻结,但所有后续计算的速度都会非常快。下面,我概述了我为解决这个问题而尝试的一系列策略。注意:我已经用Dagger注入了Exprewa
ExprEvaluator().evaluate("1+3 + (4/2)") //Kotlin
当我第一次运行测验应用程序并回答问题时,主UI线程在执行计算时会冻结,但所有后续计算的速度都会非常快。下面,我概述了我为解决这个问题而尝试的一系列策略。注意:我已经用Dagger注入了Exprewator类,它作为一个单例存在
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线程就会冻结
我注意到第一次调用evaluate总是很慢,不管传入的字符串是什么。我可以通过“1”,评估大约需要4秒,而所有后续更复杂的评估最多需要毫秒。即使我对每个单粒子计算都使用Exprewator类的新实例,如下所示:
fun evaluate(expression: String?): IExpr? {
try {
return ExprEvaluator().evaluate(expression)
} catch (e: Exception) {
throw (e)
}
我仍然得到一个缓慢的初始计算和所有后续调用的评估是闪电般的快。我真的不确定这里发生了什么,我想知道这是否是安卓系统本身的问题,繁重的计算需要至少执行一次才能使所有后续的计算顺利进行
exprevator
构造函数或其方法很可能正在引用库中的一堆内部类,所有这些类都在第一次调用时加载,但对于所有后续调用,类都已加载到内存中Ctrl+B
或您为Go->Implementation
提供的任何快捷方式),或原始源代码(如果有)。它可以帮助你了解里面发生了什么使用systrace/内存转储查找可能的泄漏或smth其他