Михаил Рубанов Profile picture
Oct 21, 2021 26 tweets 7 min read Read on X
Как я сборку ускорял

Пару недель назад столкнулся с тем, что проект долго собирается. Ну вы знаете, если программируете на iOS. Начал разбираться.

Тред
Взял тулзу xcode build times, она ставит метки вокруг каждого фреймворка. Прогнал билд, нарисовал диаграмму Ганта.

github.com/PaulTaykalo/xc…
Мы уже пару лет занимаемся распилом и 70% кода в модулях. Но тогда на графе 60% времени уходит на компиляции 30% монолита. Image
Прогнал xcodebuild с showBuildTimingSummary. Увидел, что какие-то функции компилятся очень долго. Копаем дальше. Image
Включаю варнинги от фронтенда свифта. Я никогда особо не верил в эти флаги: они обычно показывают, что у меня что-то по 0.5 секунды компилится. Я даже если все места починю выиграю секунд 20. Image
В этот раз все было намного интересней. Смотрите какой мне красавчик попался. 4.5 минуты пытается понять что я написал. Image
Вот мой чендж на миллион. Я не знаю, за сколько оно собирается сейчас, точно меньше 100мс. Т.е. больше чем в 2750 раз. Image
Там было еще несколько похожих случаев, но тип сложно было зарезолвить на уровни кложи. Решилось тоже явным указанием типа. В итоге, граф стал похож на нормальный. Image
Увы, эта проблема была только у меня, коллегам особо не мешало. Зато варнинги время сборки включили для всех, чтобы можно было найти внезапные отклонения.

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

Весной 2020 мы начали активно писать юнит-тесты. Нормальная разработка через тесты идет только тогда, когда тесты проходят быстро. Только скорости тестов недостаточно, нужна еще и моментальная компиляция.
Компьютер нельзя заставить работать быстрее, можно лишь дать ему меньше работы. Единственный вариант — писать код в модуле, тесты поверх модуля, тогда надо будет собирать минимум кода, прогонять минимум тестов.
Мы уже отделяли модули, просто усилились в этом, а с января мы трекаем прогресс распила. Оказалось, что мы скорее просто пишем в модулях, монолит едва убывает. Мы постоянно выкидываем из него код, просто и новый писать рядом приходится. Image
Быструю компиляцию мы получили именно от разработка в модуле, скорость общего билда не трекали. Очевидно, что для высокой скорости надо параллелить билд разных модулей. У нас было только одно правило — фичевые фреймворки не должны зависеть друг от друга. Так прошло полтора года.
Как знаете, недавно я задался вопросом скорости и начал смотреть.

Предыдущая визуализация меня не устраивала по куче параметров, поэтому взял данные, которые генерировал xcode build times и нарисовал свой график.

На нем несколько интересных мест. Image
Сначала идут зависимости из кокоаподс.

Конкаренси высокая, потому что у них нет зависимостей между собой, но какие-то собираются слишком долго. На самом деле, они собираются быстро, просто в процессе прерываются билдом других модулей. К — конкаренси. Image
Затем начинается жидкая струйка из разного файрбейса, плюс что-то еще подкомпиливается рядом.

По уму он должен собираться где-то в конце, ближе к основному приложению, но, видимо, на это влияет устройство подов и принцип их линковки. Жаль. Image
Ускорить этот этап можно двумя путями.
- Удалить Firebase и все его модули)))))))))))))))))))))))) Хотя бы для дебага это нам не нужно.
- Пребилдить все внешние зависимости. Можно сэкномить 20% времени
Второе интересное место — одиночная линия, после которой начинается массовая параллельность.

Это модуль с UI, он оказался очень жирным, но при этом нужен для всех модулей. Чтобы ускорить надо разделить на части. Сэкономит еще 10%.

Забегая наперед — половина времени это ассеты Image
Затем блок из разных фичевых модулей.

Они странно делятся на три части, но это потому, что сбились связи. Например, оказалось, что базовый модуль моделей зависит от UI (!! ну бывает, человек случайно туда ячейку положил). Поправив зависимости мы это все сравняли. -5%. Image
Часть фичевых модулей все-таки зависит от других.

Это нормально на текущем этапе распила, когда не все связи еще понятны. Например, карточка продукта зависит от меню, потому что использует одинаковые модели. Нужно вынести общие модели в отдельный фреймворк. Image
Пока плодить много динамических фреймворков не хочется, потому что они замедляют время запуска. Снова палки от кокоаподс, но рано или поздно мы это поправим. 5%
В конце висит 30% монолита.

Есть как минимум еще три больших фичи, которые нужно отпилить. Если приходится много работать с монолитом, то можно закешировать все остальные фреймворки, компиляция снова станет быстрой. Наверно, тут можно срезать половину, 15% Image
После пары оптимизаций фичи собрались в одном месте, но по графику конкаренси в 12 потоков. Не верю, что макбук в 4 ядра так может, но об этом позже.

Раскрасил график:
- темно-серым — внешние зависимости
- красным — блокирующие зависимости, которых ждут другие фреймворки Image
Мы сейчас в процессе перехода на Tuist. Все зависимости заменили на SPM, у них нет .xcproject, поэтому разметка перестала работать для них и нужно новое решение.

Если прекомпилировать все зависимости, то график будет такой. Image
Важна не только сборка проекта, но и тестов.

Для тестов надо собрать основной код, вспомогательный код для дублеров и сами тесты. Все это отнимает время и полный график намного красочней. Я покрасил в серый основной код, синий — дублеры, красный — тесты. Гирлянда к НГ готова. Image
Для анализа этой штуки нужно что-то посложнее. Статичной картинки уже недостаточно, нужно уметь искать связи и фокусироваться на частях.

К этому моменту оказалось, что я зашел уже далеко. В следующий раз расскажу про эту тулзу.

Если нравится тред, то можно и поретвитить.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Михаил Рубанов

Михаил Рубанов Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @akaDuality

Jan 27, 2023
Многопоточность на туалетах

Сейчас объясню многопоточку iOS так, что на всю жизнь запомнится — на туалетах!
Последовательная очередь

Есть одна кабинка, в ней помещается один человек за раз. Все желающие выстраиваются в очередь.

Можно сделать две очереди из двух туалетов для мальчиков и девочек, но внутри все равно только один унитаз.
Конкурентная очередь

В одном туалете несколько кабинок, несколько человек за раз.

Почему это не несколько отдельных последовательных очередей? Потому что две конкурентные очереди нужны для мужского и женского туалета, в каждом по несколько унитазов
Read 15 tweets
Jan 26, 2023
Как я handoff подключал

С ней Apple позволяет быстро продолжить работу на другом устройстве. Для VoiceOver Designer это полезно: рисуешь прототип на компе, тут же проверяешь как он звучит на телефон.

Было ли легко? Пришлось использовать чуть ли не весь тулинг что был под рукой
Документация: если у вас document-based application, то все заводится с полпинка — в описании файла добавляете флаг NSUbiquitousDocumentUserActivityType с каким-нибудь ключом и готово.

Заработало? Да, подсказки появились. Закончилась ли на этом фича? Нет
С айфона на мак открывается все хорошо, а вот с мака на айфон открывается только тот документ, который был открыт первым.

Пытаюсь продебажить. Начинаю с айфона, он ведь не работает. URL в айфон и правда приходит один и тот же, значит айфон нормально работает
Read 14 tweets
Dec 3, 2021
У меня появился повод вспомнить про фичу, которую сделали пару лет назад — интерфейс выбора пиццы из половинок в Додо.

Расскажу как дизайнили, почему и какие решения приняли. От идеи до прода в одном треде.
Продукт показываем крупно, в полную ширину экрана. Можно было бы еще крупнее — вынести за пределы экрана, но нам важна форма пиццы, а не начинка.
Управлять контентом напрямую кайфово, поэтому двигаем пиццы под пальцем. Получается два вертикальных списка. Выбранная пицца крупно, остальные уходят в фон, все интерактивно изменяется. смотрите в движении:
Read 10 tweets
Jul 4, 2021
Редизайним клавиатуру

Уже сотню лет никто не решается массово заредизайнить клаву. У Эпла последняя выглядит вот так. Давайте немного подвигаем кнопки и посмотрим как можно сделать лучше.
Наши пальцы двигаются впереди и назад, а не по диагонали, поэтому кнопки выравниваем в колонки.
Длина боковых клавиш нужна была только для компенсации сдвига, укоротим кнопки обратно. Не спешите бомбить за короткий энтер, его еще подвинем поудобней.
Read 31 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(