Как стать автором
Обновить
0
0

Пользователь

Отправить сообщение

Сочувствую. Reflection - это боль и по производительности, и в сочетании с R8, а kotlin-reflect еще и здоровенная либа в рантайме.

Вы пробовали закинуть issue в Retrofit? Сходу не нашел. Логично было бы создавать адаптеры в Dispatchers.IO, но возможно у них были причины так не делать.

Спасибо за любопытную и немного провокационную статью. :)

Время в 500+ миллисекунд меня сильно удивило, да честно говоря и 50 мс после исправления - это неприлично много.

Очень здорово, что вы выложили тестовый проект. Без него вряд ли удалось бы воспроизвести результаты. Погонял его на стареньком (6 лет, Snapdragon 410) аппарате, и вот что получилось (время в формате "первый запуск / последующие запуски"):

getMainThreadResult 620 / 18 мс
getRetrofitFixResult 57 / 8 мс
getWithContextResult 12 / 2 мс

Основную часть времени занимает создание reflection-based JSON-адаптера:

Замена его на kotlin-codegen дает ускорение в разы:
getMainThreadResult 92 / 11 мс
getRetrofitFixResult 63 / 8 мс (тут нет ускорения, разрыв сильно сокращается)

Но в принципе вызывать Retrofit.Builder()....create(ApiService::class.java) каждый раз по нажатию кнопки - сомнительная идея, обычно это делается единожды при старте приложения.

Такой рефакторинг ускоряет getMainThreadResult еще в разы: 25 / 3 мс

Из этих 25 мс основная часть уходит на создание CatFactResponseJsonAdapter (один раз при первом вызове любого метода, возвращающего CatFactResponse).

3 мс - это главное время, от которого имеет смысл отталкиваться. getRetrofitFixResult и getWithContextResult по-прежнему чуть быстрее (1-3 мс), но стоит ли это мучений с обертками над обертками? ;) Простые архитектурные изменения (см. выше) дают гораздо больший эффект.

Цифры выше можно рассматривать как worst-case scenario: старый аппарат, debug build без AOT-компиляции и прочих рекомендуемых хитростей.

Мораль: профайлер - наше всё. ;)

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность