Download - Android Telegram S Optimizations
![Page 1: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/1.jpg)
Оптимизация Telegram S for AndroidМетоды и принципы разработки высокопроизводительных приложений
Steve Korshakov CEO Actor [email protected]
![Page 2: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/2.jpg)
История
V2
?
![Page 3: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/3.jpg)
– Генри Форд
«Все можно сделать лучше, чем делалось до сих пор»
![Page 4: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/4.jpg)
Хорошее приложение
![Page 5: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/5.jpg)
Оптимизации
Сеть
БД
Интерфейс
Память
Оповещения
![Page 6: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/6.jpg)
Мобильные сетиTCP-Подключения часто полуживые
Очень нестабильный Ping (от 100мс до 2с)
Иногда в подключение удается отправить лишь один пакет и не получить ответа
Необходима минимизация трафика, тк часто просто нет другой возможности работать
Часто пытаются слушать трафик так, что системы слежения сами падают и теряют пакеты
![Page 7: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/7.jpg)
Высоконагруженные сервисыСервера часто умирают
Необходим эффективный протокол, который рассчитан на нагрузки
Быстрое восстановление работы при разных сбоях между клиентом и серверами
Производительность протокола напрямую связана с ценой обслуживания
![Page 8: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/8.jpg)
Эффективный HTTPНа каждый запрос 5 попыток с таймаутом в 5 секунд
Не использовать отмену запросов (вешает Apache HTTP)
LongPoll для получения событий
В сумме выходит медленно, но, в целом, стабильно и комфортно.
Официальное приложение ВК продолжает НЕ делает так, потому у него часто все плохо.
![Page 9: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/9.jpg)
MTProtoЛегкие сессии
Оптимальная криптография
Переотправка данных
Собственная бинарная сериализация
Определяет ТОЛЬКО шифрование транспорта.
![Page 10: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/10.jpg)
MTProto v2 (by Actor)Стандартная TLS криптография
Редиректы
Более гибкая сериализация
На уровне транспорта реализованы инструменты проверки связи
![Page 11: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/11.jpg)
MTProto v3?
Peer-To-Peer
Детектирование типа подключения и адаптация приложения под эти условия
Создание отдельного протокола для обмена файлами
Версия протокола для Long Fat Networks
![Page 12: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/12.jpg)
Детали реализации
Мессенджер VK писался во времена Apache HTTP, он был стабильным, сейчас считается устаревшим.
Для Телеграмма использовались синхронные сокеты, а не NIO, тк NIO в разных версиях по разному глючит. Однако, официальный клиент всегда разрабатывал на асинхронных.
![Page 13: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/13.jpg)
Работа с БДПоиск наиболее быстрой БД
![Page 14: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/14.jpg)
История списковCursorAdapter
Cached CursorAdapter
MemoryAdapter + Background Cursor
MemoryAdapter + Background ORM
MemoryAdapter + Background Cursor + Custom serialization + Memory Cache
DisplayList + Actor ListEngine
![Page 15: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/15.jpg)
5 msИли 1/3 кадра при 60 FPS
Время загрузки диалогов
![Page 16: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/16.jpg)
CursorAdapter
- Чтение из курсора в UI-потоке
- Иногда и повторное чтение
+ Подгружается сразу весь список
+ Нет сложной логики по подгрузке
+ Более гибкое управление данными
![Page 17: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/17.jpg)
Cached Cursor Adapter
Кеширование загруженных результатов
Немного исправляет производительность для тех, кто уже был отображен, но до первого обновления списка
Все равно читает с диска в UI-потоке
![Page 18: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/18.jpg)
MemoryAdapter + Background Cursor
+ UI работает только с обычным ArrayList, который обновляется и синхронизируется в фоне с БД
+ Основано на тех же запросах, что и предыдущие варианты
- Нужно реализовывать сложную логику (не слишком, но в ней легко допустить баги) и более сложные состояния списков
- При обновлении списка надо все равно с нуля пере запрашивать Cursor
![Page 19: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/19.jpg)
Оптимизация запросов SQLite
SQLite Cursors
ORMLite
GreenDao
Actor NoSQL Engines
![Page 20: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/20.jpg)
Оптимизация запросовДенормализация: убрать все Join
Например, в списке диалогов хранятся имена и аватарки пользователей и групп и обновляются вручную
Минимизировать сами таблицы и набор колонок для списка, минимизировать любые большие колонки
В итоге запись немного медленнее, но чтение становится гораздо быстрее (увы, цифр не помню)
Можно упростить таблицу и оставить только ID и BLOB, почему-то это работает быстрее.
![Page 21: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/21.jpg)
ORMБез ORM
+ Отсутствие overhead
- Более сложная работа с БД
ORMLite
+ Управление схемой из кода
- Reflection
GreenDAO
+ Малый overhead
- Необходимо писать в коде схему и генерировать необходимые классы
![Page 22: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/22.jpg)
Actor List EngineНа базе SQLite, но адаптируемый под любой Storage
Запись - id, sortKey и BLOB
Id генерируется снаружи движка
Асинхронная запись и чтение в фоновом потоке
Кеширование записей
Лишь подмножество операций: addOrUpdate, delete, clear, getItem
Используется ProtoBuf-подобная сериализация
![Page 23: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/23.jpg)
Actor Key-Value Engine
Аналогичен ListEngine
Запись - id + BLOB
Операции: addOrUpdate, remove, getItem
![Page 24: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/24.jpg)
Display ListDisplay List - список элементов, который синхронизируется с ListView
Можно изменять список из любого потока
Внутри - два списка, которые попеременно переключаются
Много одновременных изменений списка группируется
![Page 25: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/25.jpg)
BindedDisplayListBindedDisplayList - DisplayList, который связан с ListEngine
Автоматическая асинхронная подгрузка данных из БД
Возможность фильтрации списка (перезапросы в ListEngine)
Загрузка списка из центра коллекции
![Page 26: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/26.jpg)
Результат
Максимальная возможная скорость загрузки списков из SQLite
Отзывчивый интерфейс
Удобная асинхронная работа с БД
Гибкие синхронизируемые списки, которые не надо программировать
![Page 27: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/27.jpg)
Доработки?
Адаптация под RecyclerView
Документирование и упрощение использования движков
LMDB
![Page 28: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/28.jpg)
Оптимизации интерфейсовСписки, изображения и layout
![Page 29: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/29.jpg)
Пара фактов16 мс на все
Layout сложных объектов долгий. Иногда измерения проходят не один раз.
В ListView много View - все они делают layout
При обновлении списка - зачастую проходит повторный Layout (конкретно зависит от версии Android)
Лишние View - лишний рендеринг
![Page 30: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/30.jpg)
Никакой магии
Уменьшение влияния GC
Облегчение Layout
Уменьшение влияния фоновых потоков
![Page 31: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/31.jpg)
Список диалоговКаждый элемент - одно View
Проверяется повторный binding данных
Пересчитываются размеры только те, что изменились
Иногда для текста layout просчитывается в фоне
Это - единственный способ сделать быстро везде
![Page 32: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/32.jpg)
Список сообщенийРасчет размеров текста при загрузке из БД (отключаемо)
Каждое сообщение - лишь одно View с ручной отрисовкой.
Нажатие на ссылки обрабатываются вручную
Изображения грузятся в фоне и масштабируются строго под размер сообщения
Blur превью через оптимизированный native-код
![Page 33: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/33.jpg)
Работа с памятьюВыделение памяти и изображения
![Page 34: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/34.jpg)
Работа с изображениямиВСЕГДА переиспользуются Bitmap, даже на 2.2.
Ручное декодирование libjpeg
Ручная отрисовка региона Bitmap
Итог - GC спит
![Page 35: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/35.jpg)
Переиспользование памятиПри файловых операциях часто выделяются и высвобождаются небольшие массивы байт (8-16кб), что провоцировало GC
Для устранения проблемы был создан собственный аналог malloc, который кешировал выделенные массивы и переиспользовал их
В наиболее активных циклах переиспользуются объекты, а не выделяются новые (например Envelope в Actor System)
![Page 36: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/36.jpg)
ОповещенияОптимизация оповещений Google Play
![Page 37: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/37.jpg)
Google Cloud Messaging
Большие задержки (до 10 минут) в оповещениях
Иногда просто не работают
Есть устройства без GCM вообще
Итог - Написать свое.
![Page 38: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/38.jpg)
Разработка собственных оповещенийДержать всегда активное подключение
Однако, нужно быть аккуратным что бы не тратить энергию
Запуск радио происходит за 5 секунд и работает на полную мощность примерно 10-20 секунд. Затем еще минуту радио работает в среднем режиме и только после этого возвращается в спящий режим.
WiFi при этом почти не потребляет энергии.
![Page 39: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/39.jpg)
ЭнергоэффективностиВремя перехода от состояний зависят от типа сети
Потребление 3G может быть ниже чем у EDGE, тк можно за более короткое время скачать нужные данные
На WiFi можно всегда сколько угодно данных передавать и батарея не будет садиться вообще
Хорошая лекция от Google: http://www.youtube.com/watch?v=dASOm88Wh8g
![Page 40: Android Telegram S Optimizations](https://reader034.vdocuments.site/reader034/viewer/2022051213/55a97fa81a28ab25288b456e/html5/thumbnails/40.jpg)
Общая логика работы пушейУ Apple очень умные пуши. Анализируют порядка 23 параметров использования устройства и приложений. (последнее использование, движение устройства, последнее открытие приложения, активность его использования)
У гугла тупее.
Логика очень простая - поднимается коннект и раз в 10 минут на мобильных сетях отправляется пинг для проверки, на вайфае раз в 2-3 минуты (некоторые роутеры вешают коннект через 5 минут)