Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Spark: практика
разработки
высоконагруженных iOS-
приложений
Андриан Буданцов
.
• PDF Expert, Scanner Pro,
Documents, Calendars, Spark,
Printer Pro, Fluix
• 6 больших iOS/macOS
кодовых баз; большей ча...
• Почтовый клиент
• Кодовое название SmartMail
• Начата разработка в феврале 2014 года
• Первый релиз 29 мая 2015
Достаточно быстрая почта
Методология тестирования
• Субъективная оценка
• Xcode
• Тесты
Субъективная оценка: Dog Fooding
Субъективная оценка: β
Xcode
Performance Tests
- [XCTest measureBlock:]
• установить baseline!
- [RDTestCase measureBlock: limit:]
• Проверка прямо в к...
Производительность ≈ Энергоэффективность
Критические места
1. Получение
2. Обработка
3. Просмотр
кадр, 16 мс
Первый запуск,
использование,
батарейка
Сеть, холодный...
3. Просмотр почты
Просмотр: интерфейс Thread Viewer
Видели?
Задержка > 1 кадр
UICollectionView + UILabel + Autolayout
Считает ширину/высоту
Собирает элементы в письмоСобирает список писем, нужна
высот...
0
0.5
1
1.5
2
2.5
3
100 200 300 400
Время, сек.
Количество View
Производительность Autolayout
Источник: Флориан Куглер, ht...
Ручной layout
• Считаем frame всех view
• Оценка размера текста с помощью UILabel
• Меньше связей, чем с Auto-Layout => бы...
ASDisplayNode
ASDisplayNode UIView CALayer
содержит
ИЛИ
• NSObject
• Thread Safe
• -[ASDisplayNode view] содержит view
Background поток
• ASTextNode
• Измерение ширины текста (TextKit)
• Рендер текста
• ASImageNode
• Загрузка/декодирование и...
Саб-класс ASRangeController… +
Саб-класс ASTextNode…
Саб-класс ASTextNode: выделение текста
«Листание почты»
«Листание почты»
следующие и
предыдущие письма
(UI загружается
асинхронно)
Текущее письмо (тред)
Просмотр: интерфейс Message List
UITableView + UITableViewCell
• Оптимизация для GPU медленных устройств
• От множества UIView к -[UIView drawRect:]
• Влия...
2. Обработка почты
Mailcore + XML + RegEx + … + SQLite
Оптимизация регулярных выражений
(альтернативные группы)
(?>to|кому|a[n]?|à|til[l]?|para|À|destinataire|Pour)[^Sn]*+:
(?=[...
Кэширование NSRegularExpression
[NSRegularExpression regularExpressionWithPattern:options:error:]
static NSRegularExpressi...
Оптимизация регулярных выражений
(Remove case-insensitive)
(?i)(?=[tкaàtpÀd])(?>to|кому|a[n]?|à|til[l]?|para|À|destinatair...
Индексы
•Не забыть
•EXPLAIN
•Составные индексы
•DESC индексы
SQLite: Full Text Search
Проблемы с FTS4
• Язык запросов
• Не полная поддержка AND, OR, NOT в MATCH
• Долгое «прогревание» при первом запросе
• Зад...
SQLite FTS5
CREATE VIRTUAL TABLE IF NOT EXISTS messagesfts USING fts4(messagePk,
messageFrom, messageTo, subject, searchBo...
SQLite FTS5
• SQLite 3.9 + SQLITE_ENABLE_FTS5
• Нет задержек при индексировании (быстро!)
• Улучшенный язык запросов
~ 17%...
Трюки SQLite
• Несколько баз
• Задержка при индексировании/поиска не влияет на основную базу
• Миграции
• ADD COLUMN — бес...
1. Получение почты
IMAP & EWS
HTTP vs IMAP
• TCP / TLS — так же
• Больше времени на авторизацию, выбор папки
• XOAuth
• Не поддерживается NSURLSession
•...
Push-сообщения
• UIBackgroundModeFetch — не достаточно надежен
• Посылаем push-сообщения с сервере
Минутка бэкенда: SmartMail Cloud
…
APP
APNS
HTTP запрос
DB & Manager
Worker Worker
Filter & Pusher
IMAP IMAP
HTTP-Запрос в SmartMailCloud
• Авторизация к IMAP серверу (Oauth, пароль)
• Публичный ключ девайса
• Правила для отправки ...
Узкое место: время от пуша до письма
Загрузка писем по HTTP
• Тело письма (<2Мб) скачивается нашей инфраструктурой и
шифруется публичным ключом девайса
• Пуш-с...
Минутка бэкенда: SmartMail Cloud
…
APP
APNS
HTTP запрос
DB & Manager
Worker Worker
Filter & Pusher
IMAP IMAPMail
Storage
HTTP/2
• HTTP/2 быстрее HTTP/1.1
• Поддерживается, начиная с iOS 9
• Более эффективен в мелочах
• Мультиплексирование
LZFSE
• Алгоритм от Apple
• Open Source (github)
• ~ 40% быстрее ZLIB
• Spark: экономия ~ 1 секунды CPU времени
• Альтерна...
0. Запуск
Скорость запуска
• application: willFinishLaunchingWithOptions:
• Менеджер загрузки приложения
• Параллельные операции ини...
Спасибо!
@andrianbdn
andrian@readdle.com
Отдельная благодарность команде Spark и
лично Виктору, Александру, Дмитрию и Влад...
NSXMLParser vs libxml (SAX)
NSXMLParser
libxml 40% быстрее
LZFSE, zlib, Brotli, bzip2
0
0.5
1
1.5
2
2.5
0 50 100 150 200 250
Соотношение
Скорость распаковки, МиБ/сек
BZIP2 L5
Brotli...
LZFSE, zlib, Brotli, bzip2
0
0.5
1
1.5
2
2.5
0 5 10 15 20 25 30 35 40 45
Соотношение
Скорость упаковки, МиБ/сек
BZIP2 L5
B...
Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)
Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)
Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)
Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)
Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)
Upcoming SlideShare
Loading in …5
×

Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)

Известный закон Джеймса Завински гласит “Каждая программа пытается расширяться до тех пор, пока не сможет читать почту”.

В данном докладе будут рассмотрены следующие практические аспекты, возникшие при разработке популярного почтового клиента Spark (номинант “App Store Best Of 2015”):
- Высоконагруженные интерфейсы: рендеринг цепочек сообщений и списка писем — ключевых элементов почтового приложения с высокими требованиями к производительности. Разбор подходов, использующих UIKit, CoreText, AsyncDisplayKit, Core Graphics.
- Базы данных и поиск: работа с большими SQLite базами, оптимизация SQL-запросов, производительность полнотекстового поиска, опыт перехода с SQLite FTS4 на SQLite FTS5.
- Ускоряем Core Foundation: техники кэширования, производительность регулярных выражений, использование альтернативных библиотек (expat, libxml, libcurl), разгрузка applicationDidFinishLaunching, эффективная работа с многопоточностью.
- Работа в фоновом режиме и сетевое взаимодействие: энергосбережение с использованием облачной инфраструктуры; асимметричное шифрование почтовых сообщений; поддержка HTTP/2 для REST API, результаты тестирования алгоритма сжатия LZFSE.

Помимо практических аспектов, в докладе будет уделено внимание используемой в Spark методологии тестирования производительности и энергопотребления.

  • Login to see the comments

  • Be the first to like this

Spark: практика разработки высоконагруженных iOS-приложений / Андриан Буданцов (Readdle Inc.)

  1. 1. Spark: практика разработки высоконагруженных iOS- приложений Андриан Буданцов
  2. 2. . • PDF Expert, Scanner Pro, Documents, Calendars, Spark, Printer Pro, Fluix • 6 больших iOS/macOS кодовых баз; большей частью ObjC, в новых проектах Swift
  3. 3. • Почтовый клиент • Кодовое название SmartMail • Начата разработка в феврале 2014 года • Первый релиз 29 мая 2015
  4. 4. Достаточно быстрая почта
  5. 5. Методология тестирования • Субъективная оценка • Xcode • Тесты
  6. 6. Субъективная оценка: Dog Fooding
  7. 7. Субъективная оценка: β
  8. 8. Xcode
  9. 9. Performance Tests - [XCTest measureBlock:] • установить baseline! - [RDTestCase measureBlock: limit:] • Проверка прямо в коде • Защита от разницы на порядок • Тесты UI • Общее время выполнения
  10. 10. Производительность ≈ Энергоэффективность
  11. 11. Критические места 1. Получение 2. Обработка 3. Просмотр кадр, 16 мс Первый запуск, использование, батарейка Сеть, холодный старт
  12. 12. 3. Просмотр почты
  13. 13. Просмотр: интерфейс Thread Viewer Видели? Задержка > 1 кадр
  14. 14. UICollectionView + UILabel + Autolayout Считает ширину/высоту Собирает элементы в письмоСобирает список писем, нужна высота UICollectionViewCell Все работает на Main Thread
  15. 15. 0 0.5 1 1.5 2 2.5 3 100 200 300 400 Время, сек. Количество View Производительность Autolayout Источник: Флориан Куглер, http://bit.ly/2fhJbwB
  16. 16. Ручной layout • Считаем frame всех view • Оценка размера текста с помощью UILabel • Меньше связей, чем с Auto-Layout => быстрее • Много кода layout • Простор для улучшения
  17. 17. ASDisplayNode ASDisplayNode UIView CALayer содержит ИЛИ • NSObject • Thread Safe • -[ASDisplayNode view] содержит view
  18. 18. Background поток • ASTextNode • Измерение ширины текста (TextKit) • Рендер текста • ASImageNode • Загрузка/декодирование изображения • Layout • Похож на FlexBox
  19. 19. Саб-класс ASRangeController… + Саб-класс ASTextNode…
  20. 20. Саб-класс ASTextNode: выделение текста
  21. 21. «Листание почты»
  22. 22. «Листание почты» следующие и предыдущие письма (UI загружается асинхронно) Текущее письмо (тред)
  23. 23. Просмотр: интерфейс Message List
  24. 24. UITableView + UITableViewCell • Оптимизация для GPU медленных устройств • От множества UIView к -[UIView drawRect:] • Влияет на скорость создания таблицы • Большой метод -drawRect
  25. 25. 2. Обработка почты
  26. 26. Mailcore + XML + RegEx + … + SQLite
  27. 27. Оптимизация регулярных выражений (альтернативные группы) (?>to|кому|a[n]?|à|til[l]?|para|À|destinataire|Pour)[^Sn]*+: (?=[tкaàtpÀdP])(?>to|кому|a[n]?|à|til[l]?|para|À|destinataire|Pour)[^Sn]*+: На 30% быстрее! Было Стало c выносом первой буквы из альт. групп
  28. 28. Кэширование NSRegularExpression [NSRegularExpression regularExpressionWithPattern:options:error:] static NSRegularExpression *cachedRegularExpression; На 44% быстрее, тест: 1000 раз подряд, 1280 байт Было Стало после кэширования
  29. 29. Оптимизация регулярных выражений (Remove case-insensitive) (?i)(?=[tкaàtpÀd])(?>to|кому|a[n]?|à|til[l]?|para|À|destinataire|Pour)[^Sn]*+:(?-i) (?=[tкaàtpÀd])(?>to|кому|a[n]?|à|til[l]?|para|À|destinataire|Pour)[^Sn]*+: На 60% быстрее, тест: 1000 раз подряд, 1280 байт текст Было Стало без (?i)
  30. 30. Индексы •Не забыть •EXPLAIN •Составные индексы •DESC индексы
  31. 31. SQLite: Full Text Search
  32. 32. Проблемы с FTS4 • Язык запросов • Не полная поддержка AND, OR, NOT в MATCH • Долгое «прогревание» при первом запросе • Задержки до 10+ секунд при индексировании • Нагрузка на IO / CPU • Релевантность (?)
  33. 33. SQLite FTS5 CREATE VIRTUAL TABLE IF NOT EXISTS messagesfts USING fts4(messagePk, messageFrom, messageTo, subject, searchBody, tokenize=unicode61) CREATE VIRTUAL TABLE IF NOT EXISTS messagesfts USING fts5 (messagePk, messageFrom, messageTo, subject, searchBody)
  34. 34. SQLite FTS5 • SQLite 3.9 + SQLITE_ENABLE_FTS5 • Нет задержек при индексировании (быстро!) • Улучшенный язык запросов ~ 17% • Скорость поиска: FTS4 FTS5
  35. 35. Трюки SQLite • Несколько баз • Задержка при индексировании/поиска не влияет на основную базу • Миграции • ADD COLUMN — бесплатен • Пересоздание таблицы для других изменений • Несколько баз • C-функции в SQLite • atomic_write: +10% к записи на iOS
  36. 36. 1. Получение почты
  37. 37. IMAP & EWS
  38. 38. HTTP vs IMAP • TCP / TLS — так же • Больше времени на авторизацию, выбор папки • XOAuth • Не поддерживается NSURLSession • Постоянный обмен короткими пакетами • Polling / long-polling: NOOP/ IDLE
  39. 39. Push-сообщения • UIBackgroundModeFetch — не достаточно надежен • Посылаем push-сообщения с сервере
  40. 40. Минутка бэкенда: SmartMail Cloud … APP APNS HTTP запрос DB & Manager Worker Worker Filter & Pusher IMAP IMAP
  41. 41. HTTP-Запрос в SmartMailCloud • Авторизация к IMAP серверу (Oauth, пароль) • Публичный ключ девайса • Правила для отправки push-сообщений на JSON “LISP” ["or", ["has", "from", "mother@home.io"], ["has", "from", "boss@work.com"] ]
  42. 42. Узкое место: время от пуша до письма
  43. 43. Загрузка писем по HTTP • Тело письма (<2Мб) скачивается нашей инфраструктурой и шифруется публичным ключом девайса • Пуш-сообщение содержит ссылку на зашифрованное письмо • Тело письма скачивается Push Service Extension • … • PROFIT!
  44. 44. Минутка бэкенда: SmartMail Cloud … APP APNS HTTP запрос DB & Manager Worker Worker Filter & Pusher IMAP IMAPMail Storage
  45. 45. HTTP/2 • HTTP/2 быстрее HTTP/1.1 • Поддерживается, начиная с iOS 9 • Более эффективен в мелочах • Мультиплексирование
  46. 46. LZFSE • Алгоритм от Apple • Open Source (github) • ~ 40% быстрее ZLIB • Spark: экономия ~ 1 секунды CPU времени • Альтернативы: bzip2, brotli • Время сжатия на сервере?
  47. 47. 0. Запуск
  48. 48. Скорость запуска • application: willFinishLaunchingWithOptions: • Менеджер загрузки приложения • Параллельные операции инициализации
  49. 49. Спасибо! @andrianbdn andrian@readdle.com Отдельная благодарность команде Spark и лично Виктору, Александру, Дмитрию и Владимиру
  50. 50. NSXMLParser vs libxml (SAX) NSXMLParser libxml 40% быстрее
  51. 51. LZFSE, zlib, Brotli, bzip2 0 0.5 1 1.5 2 2.5 0 50 100 150 200 250 Соотношение Скорость распаковки, МиБ/сек BZIP2 L5 Brotli L11 ZLIB L5 LZFSE Источник, Squash Benchmark Unstable, http://bit.ly/2fgstiv
  52. 52. LZFSE, zlib, Brotli, bzip2 0 0.5 1 1.5 2 2.5 0 5 10 15 20 25 30 35 40 45 Соотношение Скорость упаковки, МиБ/сек BZIP2 L5 Brotli L11 ZLIB L5 LZFSE Источник, Squash Benchmark Unstable, http://bit.ly/2fgstiv

×