2017-06-23 10 views
0

私が作成しているクイズアプリのsymja androidライブラリを使って数学的計算を行っています。すべての計算は、 "1 + 3 +(4/2)"のような文字列をExprEvaluator()というライブラリ内のクラスに渡すことによって実行されます。私は私のクイズアプリを実行して、最初に質問に答えるときに使用例が私のAndroidアプリの最初の計算が遅いのはなぜですか?

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

だろう、それは計算を実行した場合と同様に、メインUIスレッドは凍結するだろうが、それ以降のすべての計算が非常に速くなります。以下では、問題を解決するために試した一連の戦略を概説しました。注意:私はダガーでExprEvaluatorクラスを注入してきた、それは戦略1シングルトン

class ChallengeUtils { 

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

として存在する:別々のスレッド 結果に計算をオフロード:初期計算時間の違いを作り、実際には至らなかったのより多くの問題では、私はメインのUIスレッドで結果が必要だったので。その後の計算はすべて通常どおり高速でした。

戦略2:SplashScreenアクティビティで簡​​単な初期計算を実行します。 結果:これは私が見つけた最良の解決策ですが、唯一の欠点は、私のスプラッシュ画面が長すぎることです。メインアプリの中に入ると、クイズはとてもうまくいく。

戦略3:スプラッシュ画面アクティビティ内の新しいスレッドで実行 結果:スプラッシュ画面の読み込みに時間がかかりすぎますが、メインスレッドで質問に回答し、他のスレッドの初期計算が完了すると、UIスレッドがフリーズします。


は、私が最初の呼び出しは、どんなに私が渡した文字列が。私は「1」に渡すことができ、常に遅くなる評価し、それ以降のすべてのより複雑な評価を取る一方で、評価が約4秒を取ることに気づきましたたかだか1ミリ秒。私はそうのように、すべてのsincle計算にExprEvaluatorクラスの新しいインスタンスを使用している場合でも:

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

私はまだ超高速です評価するために、低速初期計算し、すべてのsubsquentのコールを取得します。私はここで何が起こっているのか分かりません。それは、後のすべての計算がスムーズになるためには、重い計算が少なくとも1回は実行される必要がある、ネイティブアンドロイドの問題かどうか疑問です。

+1

可能なリークまたはスムースを見つけるためにsystrace/memoryダンプを使用する –

答えて

1
  1. メソッドで費やした時間を測定するためにプロファイラを使用してください。これは非常に便利なツールです!
  2. クラスは最初に参照されたときにランタイムに読み込まれます。その可能性があります。ExprEvaluatorコンストラクタまたはそのメソッドは、ライブラリ内の内部クラスの良い山を参照しています。これらはすべて最初の呼び出しで読み込まれますが、クラスはすでにメモリにロードされています。
  3. ライブラリの逆コンパイル済みコードを参照してください(Ctrl+B、またはGo To -> Implementationのショートカットのみ)、または元のソースがあれば参照してください。内部で何が起こるかを理解するのに役立ちます。
関連する問題