Intereting Posts
Связывание данных Kotlin Android studio errors Ошибка: com.app.android.dagger.component.AppComponent (unscoped) может не ссылаться на привязки с привязкой: Gradle не может найти тесты Android: реорганизовать множество групп переключателей в одном действии Мне нужно знать, почему? и если я изменю эту строку на "println (name + two)" ошибка решена? Как организовать несколько блоков сопрограммы и ожидания в тесте Kotlin Spek? Kotlin Bytecode – Как анализировать в IntelliJ IDEA? kotlin: как я могу вызвать функцию из выражения объекта Android загружает несколько документов firestore Как использовать CacheManager для Osmdroid и Osmdroid Создать новый экземпляр объекта Котлин Nullablity DB генерирует атрибуты Kotlin 'небезопасный вызов ошибки компиляции с помощью NULL-приемника после нулевой проверки Как сделать локальный метод расширения доступным в функции с приемником? Почему параметр Integer метода Java сопоставляется с Int, а не с типом платформы?

Почему первое вычисление в приложении для 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 ) или исходный источник, если он у вас есть. Это может помочь вам понять, что происходит внутри.