Почему первое вычисление в приложении для Android медленное, а все последующие вычисления быстры

Я использую библиотеку symja android для выполнения математических вычислений для приложения для викторины, которое я создаю. Все мои вычисления выполняются путем передачи строкой типа «1 + 3 + (4/2)» в класс внутри библиотеки, называемой ExprEvaluator (). Пример использования

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

Когда я запускаю приложение для викторины и отвечаю на вопрос в первый раз, основной поток пользовательского интерфейса замерзнет, ​​когда он выполнит расчет, но все последующие вычисления будут невероятно быстрыми. Ниже я изложил кучу стратегий, которые я пробовал, чтобы решить проблему. Примечание. Я ввел класс ExprEvaluator с помощью кинжала, и он существует как одноэлементный

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

Стратегия 1: Выгрузить вычисление в отдельный поток. Результат: не повлиял на начальное время вычисления и фактически вызвал больше проблем, потому что мне нужен результат в основном потоке пользовательского интерфейса. Все последующие вычисления были быстрыми, как обычно.

Стратегия 2: Запустите простой начальный расчет в моей активности SplashScreen. Результат: Это лучшее возможное решение, которое я нашел, но единственным недостатком является то, что мой экран заставки занимает слишком много времени. Когда-то внутри основного приложения викторина работает очень хорошо.

Стратегия 3: Запуск в новой теме внутри действия экрана Splash Результат: Это решило проблему заставки, которая слишком долго загружалась, но если я отвечу на вопрос в основном потоке и проверьте его правильность до того, как начальное вычисление другого потока будет завершено , зависает нить пользовательского интерфейса.


Я заметил, что первый вызов для оценки всегда будет медленным, независимо от того, какую строку я передаю. Я мог бы пройти в «1», и оценка займет около 4 секунд, а все последующие более сложные оценки будут принимать не более полусекунд. Даже если я использую новый экземпляр класса ExprEvaluator для каждого вычисления sincl, например:

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

Я все еще получаю медленное начальное вычисление, и все подсеточные вызовы для оценки являются молниеносно. Я не совсем уверен, что здесь происходит, и мне интересно, является ли это проблемой родного андроида, когда тяжелые вычисления должны выполняться хотя бы один раз, чтобы все последующие вычисления были плавными.

  1. Используйте профилировщик для измерения времени, затраченного на методы, это довольно полезный инструмент!
  2. Классы загружаются во время выполнения, когда они упоминаются вначале, вероятно, что конструктор ExprEvaluator или его метод ссылаются на хорошую груду внутренних классов внутри библиотеки, которые все загружаются при первом вызове, но для всех последующих вызовов классы уже загружен в память.
  3. Попробуйте просмотреть декомпилированный код библиотеки (просто Ctrl+B или любой ярлык, который у вас есть для Go To -> Implementation ) или исходный источник, если он у вас есть. Это может помочь вам понять, что происходит внутри.
Intereting Posts
Устаревший Kotlin Runtime Как изменить текст и функцию кнопки в Android? «Невозможно преобразовать объект типа java.lang.String в тип com.android.projectrc.Listing» при использовании Firebase RecyclerAdapter Расширение TreeMap в Kotlin не работает Файл-файл TornadoFX Что такое эквивалент Kotlin строки Java ? Можно ли анализировать кодовое покрытие Android Kotlin с помощью SonarQube? @uncheckedVariance в Котлине? Неверное поведение Maybe <List <T >> в комнате? Местная поздняя инициализация в Котлине Параметр принудительного типа должен быть инвариантным на сайте-участнике, когда он является ковариантным на сайте объявления Как проверить, что изображение было изменено, если в коде HTML нет изменений? Android – Kotlin – объект должен быть объявлен абстрактным или реализовать абстрактный элемент Как обновить элемент в ArrayList без знания индекса в Android с базой данных Firebase Realtime? Связанные свойства не работают