Часът започва: Как да оптимизирате времето за компилиране в единство

Миналият петък отбеляза пускането на Unity 5.3.5p7, незначителен пластир, който премина без предупреждение или фанфари. В този пластир обаче има точка на куршум, сгушена сред множеството други поправки, която заслужава много повече внимание.

Това е вярно. Оптимизирането на времето за компилация се завърна! * След надстройката времето за моята компилация премина от приблизително 17 секунди до 6,3 секунди.

* (След Unity 5.2.4 повечето версии имат грешка в компилатора, която отменя най-ефективната стратегия за оптимизиране на времето за компилиране)

Но аз не съм тук само за да опиша колко е невероятно да чакаш 10 секунди по-малко всеки път, когато правиш промяна на кода, тук съм да попитам: Защо повече хора не се вълнуват да видят тази грешка? Мисълта за намалено време за компилация не предизвиква радост у другите?

На снимката: Няма достатъчно радост.

Единственото ми заключение е, че повечето хора не осъзнават, че могат да оптимизират времето за съставяне. Няма официална документация и съответните публикации на форума са остарели, така че да се получи общата картина не е лесно. Но след като имате това, намаляването на времето за компилация е просто и ползите са огромни.

И така, ето моята лична стратегия за борба с времето за компилиране:

1. Вземете фактите

Първо трябва да разберете колко време отнема компилирането на вашия код. За моята собствена кодова база за едно лице, тя се движи около 17 секунди. За по-големите отбори справедливата оценка би била около 30 секунди. За да направя това в перспектива, правя около 20–30 промени на час и трябва да изчакам 30 секунди, вместо 6,3 секунди, ще добавя около 10 минути чакане около моя график на час.

Представете си колко струва през деня. През цялата седмица. Всеки месец. След това умножете това число по броя на хората в екипа. И не става въпрос само за загубеното време: По-дългото време за компилация означава, че е много по-вероятно да се разсеете и да започнете да проверявате своя имейл или Facebook.

Но първо трябва да знаете времето за компилиране. И винаги искате да го следите, така че да не проверявате нещо, което го увеличава драстично. Спомняте ли си цялото загубено време? За да го реша, написах разширение за редактор, което можете да изтеглите от моя Github тук.

2. Оптимизирайте!

Преди да оптимизираме, позволете ми да ви дам някои предимства за това как работи всичко това. В момента, в който направите промяна на кода, Unity прекомпилира кода си в .dll (компилиран код), наречен Assembly-CSharp.dll (или Assembly-UnityScript и т.н., ако не пишете на C #).

За да намалите времето, необходимо за прекомпилиране, можете да използвате специални папки, които Unity компилира в отделен .dll, наречен Assembly-CSharp-firstpass.dll. Ключовата част е, че кодът в този .dll няма да се прекомпилира, ако не го промените. Тези специални папки се наричат ​​приставки и стандартни активи и трябва да съществуват в директорията от най-високо ниво в „Активи“.

Неща, които трябва да се отбележи:

  • Поради реда, в който тези .dlls са компилирани, кодът в този firstpass.dll няма да може да препрати код извън него.
  • Промяната на кода в специалните папки ще прекомпилира както .dlls, така и ще отмени всички печалби от оптимизация.

Имайки това предвид, най-добрите кандидати за оптимизация са секции от код, които не зависят от друг код и е малко вероятно да се променят. Активите на трети страни са перфектни. Други части от вашата кодова база могат да имат смисъл да се оптимизират също.

Обаче намерих проблем с просто плъзгане и пускане на всичките ми активи на трети страни в папката Plugins. Някои от тези активи зависят от ресурсите им, които се намират в първоначалния им внесен път и се разпадат ужасно, когато това не е така. За да си спестя време, си купих Mad Compile Time Optimizer ($ 15) ***, защото той оставя некодовите файлове там, където са и също така идва с хубава функция Revert.

*** Не съм свързан с Mad Compile Time Optimizer по никакъв начин.

3. Погледнете други заподозрени

Сега, когато вашите активи на трети страни са оптимизирани, трябва да видите огромно намаляване на времето за компилиране. Обикновено там хората спират, но все пак има няколко места, на които можем да проверим за повишаване на производителността.

Атрибутът [InitializeOnLoad] е едно такова място. За непознатите, InitializeOnLoad е атрибут Unity, който може да бъде добавен към всеки клас, така че статичният конструктор да бъде извикан при стартиране на редактора (или завършване на компилация). Всеки неефективен код там може да добави нетривиални количества време към времето ви за компилиране.

След някои експерименти открих, че, да, кодът, който се изпълнява по време на InitializeOnLoad, се отчита към общото време за компилиране.

За да анализирам случаи на InitializeOnLoad, регистрирах време, отнесено от началото до края на всеки статичен конструктор със съмнително изглеждащ код. Повечето случаи на InitializeOnLoad бяха безобидни (0,0–0,2 сек), но попаднах на един клас, който злоупотребяваше с него за зареждане и кеширане на ресурси. Смених оскърбителното парче код, за да мързеливо кеширам, когато е необходимо, и продължих.

Последното нещо, което трябва да проверите, е вашият собствен код. Има ли класове, които не се използват? Вероятно нямате нужда от тях да отделят време във вашия проект. Не съм измислил добър начин да регистрирам времето за съставяне на файл от клас, но като общо правило, размерът на файла е добро приближение за сложност.

Визуализацията е най-лесният начин да определите приоритет какви файлове си струва да разгледате. Използвах GrandPers перспектива (Mac), защото може да филтрира резултатите по персонализирани правила. В крайна сметка направих филтър, който съответства на имена, завършващи с .cs и друг, за да премахна файлове с пътища, съдържащи „Приставки“ или „Стандартни активи“.

Ето как изглежда кодовата база на моя проект в края на оптимизацията. Обърнете внимание, че личният ми код е единственият компилиран код след промяна!

Да, това е всичко. Някои от тези класове TextMeshPro са масови.

TL; DR:

  • Специални папки са фиксирани в Unity 5.3.5p7
  • Винаги проследявайте времето си за компилиране (Компилиране на време за проследяване)
  • Оптимизирайте чрез преместване на активи на трети страни към активи / приставки или активи / стандартни активи (препоръчвам Mad Compile Time Optimizer)
  • Не злоупотребявайте [InitializeOnLoad]

Интересувате се автоматично да валидирате играта си, за да предотвратите счупване на изградени? Или може би да използвате аниматора като машина с ограничено състояние, вместо да изграждате собствена реализация? Вижте и другите ми статии!