Hodiny hodin: Jak optimalizovat čas kompilace v jednotě

Minulý pátek se objevilo vydání Unity 5.3.5p7, menší záplaty, která prošla bez předchozího upozornění nebo fanfár. V této opravě je však mezi zástupy dalších oprav zasunuta odrážka, která si zaslouží mnohem více pozornosti.

To je správně. Optimalizace kompilačního času je zpět! * Po upgradu se můj kompilační čas prodloužil z přibližně 17 sekund na 6,3 sekund.

* (Po verzi Unity 5.2.4 má většina verzí chybu kompilátoru, která neguje nejefektivnější strategii optimalizace kompilace)

Ale nejsem zde jen proto, abych popsal, jak úžasné je čekat o 10 sekund méně pokaždé, když provedete změnu kódu, ale musím se zeptat: Proč není více lidí nadšeno, když vidí tuto chybu opravenou? Nezpůsobuje myšlenka zkrácených časů kompilace v jiných radost?

Na obrázku: Nedostatek radosti.

Můj jediný závěr je, že většina lidí si neuvědomuje, že mohou optimalizovat čas kompilace. Neexistuje žádná oficiální dokumentace a relevantní příspěvky na fóru jsou zastaralé, takže získání celkového obrazu není snadné. Ale jakmile to budete mít, zkrácení času kompilace je jednoduché a výhody jsou obrovské.

Tady je moje osobní strategie boje s kompilací času:

1. Získejte fakta

Nejprve musíte zjistit, jak dlouho trvá, než se váš kód zkompiluje. U mé vlastní kódové základny pro jednu osobu se to pohybovalo kolem 17 sekund. U větších týmů by byl spravedlivý odhad kolem 30 sekund. Abych to uvedl v perspektivě, dělám asi 20–30 změn za hodinu a musel bych čekat 30 sekund namísto 6,3 sekund, což by přidalo dalších 10 minut čekání kolem mého plánu za hodinu.

Představte si, kolik toho za den narůstá. Po celý týden. Každý měsíc. Poté vynásobte toto číslo počtem lidí v týmu. A nejde jen o promarněný čas: Delší doba kompilace znamená, že se mnohem více rozptýlíte a začnete kontrolovat svůj e-mail nebo Facebook.

Nejprve však musíte znát svůj kompilační čas. A vy to chcete neustále sledovat, abyste nekontrolovali nic, co by to drasticky zvyšovalo. Pamatujete si všechny promarněné časy? Abychom to vyřešili, napsal jsem rozšíření editoru, které si můžete stáhnout z mého Githubu zde.

2. Optimalizace!

Než optimalizujeme, dovolte mi, abych vám poskytl několik informací o tom, jak to všechno funguje. V okamžiku, kdy provedete změnu kódu, Unity překompiluje váš kód do .dll (kompilovaného kódu) s názvem Assembly-CSharp.dll (nebo Assembly-UnityScript atd., Pokud nepíšete do C #).

Chcete-li zkrátit dobu potřebnou k překompilaci, můžete použít speciální složky, které Unity zkompiluje do samostatného dll s názvem Assembly-CSharp-firstpass.dll. Klíčovou součástí je, že kód v tomto .dll nebude zkompilován, pokud jej nezměníte. Tyto speciální složky se jmenují Pluginy a Standardní aktiva a musí existovat v adresáři nejvyšší úrovně v části Aktiva.

Zajímavosti:

  • Z důvodu pořadí, ve kterém jsou tyto soubory DLL zkompilovány, nebude kód uvnitř tohoto firstpass.dll schopen odkazovat mimo něj.
  • Změna kódu uvnitř speciálních složek zkompiluje dll a znemožní zisky z optimalizace.

S ohledem na to jsou nejlepší kandidáti na optimalizaci oddíly kódu, které nezávisí na jiném kódu a pravděpodobně se nezmění. Aktiva třetích stran jsou perfektní. Optimalizace mohou mít smysl i jiné části vaší kódové základny.

Nalezl jsem však problém s pouhým přetažením všech svých aktiv třetích stran do složky Pluginy. Některá z těchto aktiv závisí na jejich zdrojích, které se nacházejí na jejich původní importované cestě, a pokud tomu tak není, hrozně se zlomí. Abych si ušetřil čas, koupil jsem si Mad Compile Time Optimizer (15 $) ***, protože to nechává soubory bez kódu tam, kde jsou, a také přichází s pěknou funkcí Vrátit.

*** Nejsem nijak spojen s Mad Compile Time Optimizer.

3. Podívejte se na další podezřelé

Nyní, když byla vaše aktiva třetích stran optimalizována, byste měli zaznamenat obrovské zkrácení času kompilace. To je obvykle místo, kde lidé přestanou, ale stále existuje několik míst, kde můžeme zkontrolovat zvýšení výkonu.

Jedním takovým místem je atribut [InitializeOnLoad]. Pro ty, kteří nejsou obeznámeni, je InitializeOnLoad atribut Unity, který lze přidat do libovolné třídy, takže statický konstruktor je vyvolán při spuštění editoru (nebo dokončení kompilace). Jakýkoli neefektivní kód, který by tam mohl přidávat netriviální množství času k vašemu času kompilace.

Po několika experimentech jsem zjistil, že ano, kód, který běží během InitializeOnLoad, se počítá do celkového času kompilace.

Pro analýzu instancí InitializeOnLoad jsem zaznamenal čas od začátku do konce jakéhokoli statického konstruktoru s podezřelým kódem. Většina případů InitializeOnLoad byla neškodná (0,0–0,2 s), ale narazil jsem na jednu třídu, která ji zneužívala k načtení a uložení mezipaměti. V případě potřeby jsem přestupující část kódu změnil na línou mezipaměť a pokračoval dál.

Poslední věcí, kterou je třeba zkontrolovat, je vlastní kód. Existují třídy, které se nepoužívají? Pravděpodobně je nepotřebujete, aby ve vašem projektu zabrali čas. Neuvažoval jsem o dobrém způsobu protokolování času kompilace pro soubor třídy, ale obecně je velikost souboru dobrou aproximací složitosti.

Vizualizace je nejjednodušší způsob, jak upřednostnit, jaké soubory stojí za to se na ně podívat. Použil jsem GrandPerspective (Mac), protože dokáže filtrovat výsledky podle vlastních pravidel. Nakonec jsem vytvořil filtr, který odpovídá jménu končícím .cs a dalším, abych odstranil soubory s cestami, které obsahovaly „Pluginy“ nebo „Standardní aktiva“.

Na konci optimalizace vypadal kodebase mého projektu. Mějte na paměti, že můj osobní kód je jediný kód, který se kompiluje po změně!

Ano, to je celý kód. Některé z těchto tříd TextMeshPro jsou obrovské.

TL; DR:

  • Speciální složky jsou opraveny v Unity 5.3.5p7
  • Vždy mějte čas kompilace (Compile Time Tracker)
  • Optimalizujte přesunutím aktiv třetích stran na Aktiva / Pluginy nebo Aktiva / Standardní aktiva (doporučuji Mad Compile Time Optimizer)
  • Nezneužívejte [InitializeOnLoad]

Zajímá vás automatická validace vaší hry, aby se předešlo rozbitým sestavám? Nebo možná používáte animátor jako konečný stavový stroj místo vytváření vlastní implementace? Podívejte se na mé další články!