Активация за 5 минут

Вынесите тяжёлые
сборки Xcode в облако M4

$21.2 / день · выделенное железо
Арендовать сейчас
16 ГБ унифицированной памяти SSH / VNC

Clean build Xcode в реальных условиях: локальный MacBook или выделенный облачный M4 — кто быстрее?

Больше targets, макросы Swift — и сборка Xcode из «на время кофе» превращается в «на время обеда». Мы замерили одно и то же SwiftUI-приложение среднего размера на MacBook Air M2 (8 ГБ) и Mac mini M4 (16 ГБ выделенной памяти) на узле SpinMac Сингапур: полный clean build в Debug, инкрементальная сборка одного файла и Release Archive. Реальное время, давление swap и нагрев корпуса задокументированы вместе с воспроизводимым сценарием «код локально — сборка в облаке».

Почему локальные сборки на MacBook замедляются

Многие инди-разработчики и небольшие команды работают на MacBook Air или базовом MacBook Pro — удобно и экономно по энергии, но часто с 8 или 16 ГБ RAM. При открытом Xcode, Simulator, десятке вкладок Chrome, Slack и Preview физической памяти для swift-frontend и ld остаётся мало. macOS начинает вытеснять DerivedData и кэши индекса на SSD. Кажется, что «сборка просто на пару минут дольше», но на деле пропускная способность памяти уходит в swap, и каждая следующая инкрементальная сборка становится чуть тяжелее.

Часто упускают из виду термальное ограничение. Охлаждение ноутбука имеет предел; после 8–15 минут полной сборки частота CPU может упасть на 15–25 %, а шум вентиляторов мешает видеозвонкам. Mac mini в стойке дата-центра охлаждается стабильно — идеален как выделенная машина сборки, пока ноутбук остаётся свободным для редактирования и созвонов.

Эта статья отвечает на конкретный вопрос: на масштабе реалистичного проекта, сколько выигрывает перенос компиляции на выделенный узел M4 SpinMac? Какова цена? Когда облако не стоит усилий?

Тестовое окружение и методика

Для воспроизводимости: одна версия Xcode, одна процедура очистки DerivedData, замер через xcodebuild и /usr/bin/time -l, чтобы исключить индексацию GUI и фоновые задачи. Перед каждой серией: rm -rf ~/Library/Developer/Xcode/DerivedData/*, закрыты лишние приложения.

Тестовое окружение

Локально A: MacBook Air M2 · CPU 8 ядер · 8 ГБ унифицированной памяти · SSD 256 ГБ · macOS 15 Sequoia.
Локально B (контроль): MacBook Pro 14" M1 Pro · CPU 10 ядер · 16 ГБ унифицированной памяти · SSD 512 ГБ · тот же OS.
Облако: SpinMac Mac mini M4 · CPU 10 ядер · 16 ГБ унифицированной памяти · SSD NVMe 256 ГБ · выделенный канал 1 Gbps (узел Сингапур).
Toolchain: Xcode 16.4, Command Line Tools совпадают.
Сэмплирование: memory_pressure для swap; powermetrics каждые 5 с для частоты CPU; уровень шума вентилятора на расстоянии 30 см от корпуса.

Тестовое приложение: внутреннее SwiftUI «PulseTrack» — около 82 000 строк Swift, четыре target (основное приложение, Share Extension, Widget Extension, Watch App), шесть зависимостей SPM (включая Alamofire, Kingfisher). Средний размер для App Store — не гигантский монорепозиторий, но достаточный, чтобы нагрузить машину с 8 ГБ.

Три сценария сборки и команды

Три типичные ситуации: от ежедневной итерации до публикации в App Store.

Сценарий 1: полный clean build (Debug)

Имитирует первый checkout в CI или холодный старт после смены ветки:

xcodebuild -scheme PulseTrack -configuration Debug -destination 'platform=iOS Simulator,name=iPhone 16 Pro' clean build CODE_SIGNING_ALLOWED=NO

Подпись отключена, чтобы изолировать компиляцию. Три прогона на машину, берётся медиана.

Сценарий 2: инкрементальная сборка одного файла

Изменение одного Swift-файла (~40 строк UI-логики), затем сборка без clean. Самое частое действие в работе, очень чувствительно к свободной RAM и состоянию индекса.

Сценарий 3: Release Archive

Полный Archive с Distribution-сертификатом, оптимизацией (-O) и без bitcode. Максимальная длительная нагрузка на CPU — типичный сценарий троттлинга на ноутбуке.

О честности сравнения

Локальный B (M1 Pro 16 ГБ) — контрольная группа «уже неплохой ноутбук», чтобы отделить выигрыш M4 в облаке от поколения чипа и от того, что машина только собирает, не деля RAM с остальным. Облачные замеры по SSH; сетевая задержка не входит в таймер (исходники предварительно синхронизированы через rsync).

Сравнение времени: ключевые цифры

Медиана трёх серий ниже. M4 в облаке лидирует во всех трёх случаях; максимальный разрыв на Archive — проходы оптимизации требуют устойчивой нагрузки, а охлаждение в стойке удерживает частоты.

5′18″ M4 облако, полный Debug
11′42″ Air M2 8 ГБ, полный Debug
2,2× Выигрыш clean build
0 ГБ Прирост swap в облаке
Сценарий MacBook Air M2 · 8 ГБ MacBook Pro M1 Pro · 16 ГБ SpinMac M4 · 16 ГБ
Полный clean build (Debug) 11′42″ 7′08″ 5′18″
Инкремент одного файла 48″ 26″ 17″
Release Archive 18′35″ 11′20″ 8′12″
Пик использования swap 2,8 ГБ 0,4 ГБ 0 ГБ
Шум вентилятора при сборке (пик) 46 дБ 41 дБ (дата-центр — н/д)

На Air M2 заметный swap появляется примерно на шестой минуте clean build (system-wide memory free percentage около 4 % в memory_pressure). Суммарная загрузка CPU процессов swift-frontend падает с ~680 % до ~420 % — дело не в «тормозящем Xcode», а в подкачке ядра. M4 в облаке держал все десять ядер на 85–92 % без зафиксированного троттлинга.

Локальный M1 Pro 16 ГБ в полном clean build был лишь ~34 % медленнее облачного M4 — намного меньше, чем коэффициент 2,2 у Air 8 ГБ. Объём памяти часто становится узким местом раньше поколения чипа. При 16 ГБ локально смысл облака смещается от «сырой скорости» к «выделенная сборка без помех в повседневной работе».

Параллельная нагрузка: Simulator открыт во время сборки

Предыдущая таблица — «чистый стол». На практике Simulator для превью UI часто работает во время полной пересборки (смена конфигурации, очистка DerivedData и т.д.).

При такой комбинированной нагрузке Simulator на Air M2 нередко падает ниже 20 ips, а clean build растёт с 11′42″ до 14′28″. M1 Pro: 8′45″ — терпимо. M4 в облаке с превью Simulator по VNC: лишь ~40 с больше (5′58″), потому что обе нагрузки получают RAM и CPU, не деля 8 ГБ.

После трёх clean build DerivedData на Air достигает 4,7 ГБ — приемлемо на SSD 256 ГБ, но при 8 ГБ RAM кэш индекса конкурирует с артефактами сборки. На облачных узлах доступно расширение SSD +1 ТБ (от $2,5/день) для команд, хранящих несколько кэшей веток.

Ошибки, из‑за которых сравнение теряет смысл

Если эти детали расходятся, результат может отличаться на 30 % и больше:

  1. 01
    Сборка до завершения индексации

    При первом открытии фоновая индексация может съесть 2–4 ГБ. Дождитесь окончания или используйте xcodebuild, чтобы убрать шум GUI.

  2. 02
    Разные настройки Build System

    С обеих сторон: New Build System и одинаковый COMPILER_INDEX_STORE_ENABLE, иначе инкрементальное время несопоставимо.

  3. 03
    Синхронизация исходников в облако

    rsync --delete для согласованного workspace. Не собирайте с смонтированного по сети FUSE-диска — сетевой I/O станет невидимым узким местом.

  4. 04
    Архитектура симулятора

    Симулятор Apple Silicon по умолчанию arm64. Сборка ещё и под x86_64 на одной машине может почти удвоить время.

О виртуализированных macOS-хостах

Некоторые VPS-продавцы предлагают виртуализированный или перегруженный macOS без полного toolchain Xcode и стабильной квоты CPU. Мы намеренно использовали выделенные физические Mac mini M4 у SpinMac — clean build на виртуализации часто «плавает» на 40–60 % и плохо подходит как эталон.

Удалённый workflow: разработка локально, сборка в облаке

При 8 ГБ или ноутбуке 16 ГБ между созвонами и разработкой не обязательно продавать машину ради Mac Studio. Прагматичный путь: вынести сборку Xcode и нагрузку Simulator в облако, редактор и Git оставить локально.

Типичная ситуация: демо в 15:00, коллега пушит ветку с полной пересборкой, вентиляторы на максимуме, Zoom дёргается — это не вопрос навыков, а делёжки ресурсов. Облачный узел M4 от $21,2/день: включить на неделю релиза, выключить потом — часто дешевле апгрейда железа.

  1. 01
    Поднять узел SpinMac

    Выберите регион (Сингапур / Япония Токио / Корея Сеул / Гонконг, Китай / США Восток). SSH и VNC за 1–5 минут. См. центр помощи.

  2. 02
    Синхронизировать код и зависимости

    Первый перенос: rsync -avz --exclude DerivedData ./ user@host:~/PulseTrack/. На узле: xcodebuild -resolvePackageDependencies для SPM.

  3. 03
    Редактировать локально или по SSH, собирать удалённо

    VS Code Remote SSH или Cursor Remote; команды сборки в SSH-сессии. Превью UI через браузерный VNC и Simulator при необходимости.

  4. 04
    Подключить как CI runner (опционально)

    Тот же узел как self-hosted runner GitHub Actions. Шаги в руководстве CI/CD Xcode на облачном Mac.

Пять регионов дают выделенный 1 Gbps и публичный IPv4. Из офиса в Москве до Сингапура: инкрементальный rsync ~120 изменённых файлов за 4–8 секунд — пренебрежимо для инкрементальных workflow. Для APAC — Сингапур или Япония; для рынка США — США Восток.

Стоимость и уместность: когда облако оправдано

Ваша ситуация Рекомендация Роль облака
MacBook Air 8 ГБ, постоянный swap Сборки + Simulator на M4 в облаке Посуточная аренда, недели релиза
16 ГБ локально, OK, но вентиляторы мешают созвонам Full / Archive в облаке, инкремент локально Гибридный workflow, меньше шума
Команда 3–10 человек, одна машина сборки Постоянный M4 в облаке + CI runner $106,1/мес., выделенно, без очереди
Mac Studio 64 ГБ, узких мест нет Облако опционально Кластер TB5 для параллельных Archive

Быстрый расчёт: clean build с 12 до 5 минут, шесть сборок в день → ~42 минуты экономии. По часовой ставке разработчика полдня может окупить $21,2 узла — не считая вентиляторов, качества звонка и батареи. Облако не заменяет ноутбук: оно даёт сборкам выделенное физическое железо без прерываний.

Чтобы автоматизировать pipeline, см. руководство по GitHub Actions и Jenkins. Параллельные Archive на нескольких машинах: бенчмарк кластера Thunderbolt 5.

Выделенное железо · Активация за 5 минут

Выделенный M4 для сборок Xcode — без отъёма RAM у ноутбука

Выделенный узел SpinMac Mac mini M4: 16 ГБ унифицированной памяти, полный Xcode, доступ SSH / VNC, пять регионов, от $21,2/день без долгосрочных обязательств.

$21.2 / день
ЧипApple M4
CPU10 выделенных ядер
Память16 ГБ унифицированной
Neural Engine38 TOPS
SLA99,9 %
Запуск1–5 минут