Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Unity assembly definition files slower, not faster - how to compile faster?

Discussion in 'Editor & General Support' started by nicmarxp, Jan 4, 2018.

  1. nicmarxp

    nicmarxp

    Joined:
    Dec 3, 2017
    Posts:
    341
    I get impatient having to wait 5-7 seconds between each code change, to be able to start playmode, or get an update if the playmode is already running. So I took a look at Assembly definition files, but I'm not sure if I'm doing something wrong.

    At first I tried the example project, and it changed from 7 to 3 seconds after adding the asmdef (I only tested the interdependentScripts scripts and assembly definition feature).

    Before I tried this on my own project, the compile time was 5.5 seconds. When I added assembly definition files, let it compile (20s the first time), and then change one of the files, I get about 7 seconds compile time. So it’s slower with the Assembly definition files.

    With a super simple project with only one script + the CompileTime script, the compile time is 3.5 seconds. Is that the best I can get on my computer, or is there anything else that can speed it up?

    I have a Macbook Pro 15" Late 2016 (2,7 GHz Intel Core i7). What are the shortest possible compile times on a better computer? Is there any point in upgrading to a better computer, or is this what to expect from Unity?

    Here’s my folder structure. I have a few scripts, and some 3rd party Unity Sample UI which can be deleted later. Is there anything I could change to make compilation faster?

    Note that I tested first putting an asmfile (forgot the asm-prefix I used elsewhere) in the 3rd-Party folder, but I wasn't sure if it was grabbing subfolders or not...

     
  2. nicmarxp

    nicmarxp

    Joined:
    Dec 3, 2017
    Posts:
    341
    I made a "Standard Assets" folder, and moved Editor, GUI and Utils into that and managed to down the time to 4.6 seconds. So at least I save a second of my life each time.. :)
     
  3. steffen-itterheim

    steffen-itterheim

    Joined:
    Nov 10, 2015
    Posts:
    24
    Two things that are worth mentioning:
    • If you change a script in a asmdef which is referenced by all (most) other assemblies, the compilation will also compile all the referencing assemblies, ie you'll get a (near) full rebuild.
    • If you change a script in an asmdef not referenced elsewhere, compilation should be faster than rebuilding the entire project with no asmdefs at all.
    • Always test changes to a single script file, not a rebuild all.
    I guess an initial build (full rebuild) would be slower with many asmdef but as you work on individual features compile times should increase.

    I did a quick test in our most complex project with 422 .cs files under Scripts (more under Plugins). It takes 11 seconds to compile a script in our "Scripts" assembly. We just yesterday added asmdefs and made it work, so "Scripts" is not further subdivided at the moment.

    I added a new folder with a single monobehaviour script and an asmdef. When I change this script, compilation takes 8 seconds or a little less.

    I count the time the rotating wheel in the lower right corner appears until it disappears. For this particular project, it stops animating far earlier than for it to go away. Something about our project, perhaps some post-compile steps or something, makes this last part with the wheel "stuck" about as long as the wheel animating.

    If the animation of that spinning wheel is an indicator of the script compilation phase then I get the following results:
    - change of "Scripts" assembly: 7 seconds (wheel animation)
    - change in "asmdeftest" assembly: 3.5 seconds (wheel animation)

    So using asmdef helps compile times. But personally I'm more interested in how asmdef helps splitting up code, ie it effectively prevents too many undesirable direct references in code. They also become visible by looking at the asmdef ... you may notice that one day the Input module has a reference to the Network module and then you question the necessity of that reference and investigate... while previously you would have to look and find that reference somewhere in one of the input scripts - which happened randomly at best.

    PS: I'm using Windows 10.
     
  4. nicmarxp

    nicmarxp

    Joined:
    Dec 3, 2017
    Posts:
    341
    Thanks for the feedback, didn't see that animated wheel though. I'm using mac, will look for it next time.. :)
     
  5. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    I had a similar experience where it's really doubtful if it's any faster. I have 2s compile time in a new project and in my big project it takes around 8s.

    I created the assembly definitions files and then created a new folder with a single script to see just how long it would take to compile, it took around 8s. Maybe I did something wrong or assembly definition is really not that great.
     
  6. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,036
    The problem is how this feature was promoted. When you change a script a bunch of checks are done, the actual code compilation is a small part of all of those. So it does speed up compilation time, but compilation time just isn't what takes most of the time.

    FYI it's better on small projects, the larger projects get, the less time is spent in actual compilation as a percentage. At least that is what I have observed.
     
  7. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    I guess the question is this then:

    How do you get faster times after saving scripts when developping a game with lots of scripts?
    I have a 1000 scripts right now but by the end of the game I'm working on I might have 5000.

    What do other game devs do to work fast on big projects?
     
    JimmyCushnie likes this.
  8. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,036
    On a decent sized 3d project I have average 20 second wait for every script change. I don't think the number of scripts or amount of code matters at all, because I can see how long it takes MCS to compile.

    What appears to matter most is the number of assets you have with script references. Unity appears to take most of it's time validating those and possibly updating some internal data and such.

    So the only thing you really can do is move a lot of common logic outside unity, which I do anyways for other reasons like unit testing. And just adjust your coding flow to save less frequently.
     
  9. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    Alright, it just seems a waste then that when I create a new script with a new assembly and that it's not linked to any prefabs/assets/scripts it still takes a long time to process.
     
  10. steffen-itterheim

    steffen-itterheim

    Joined:
    Nov 10, 2015
    Posts:
    24
    Speed is not the only benefit for Assembly Definitions. The possibly even bigger benefit is enforced modularity.

    So for instance, in the past we had this problem a lot, mainly with "Unity Developers" as opposed to "Experienced Programmers" but even the latter are prone to making terrible shortcuts.

    Imagine you have these subsystems in your project:
    • Game / Business Logic with Data
    • GUI
    • Network
    • Animations
    • VR Controllers
    • many, many more ... some of which you can't even tell whether they are GUI, Logic, Animation, Network ... probably a little of everything. And they're called VariableManager, SystemManager, ProviderManager, ControllerManager, AdministrationManager, BehaviourManager, ...
    Soooo ... you need the GUI to react to a Controller input? Easy, just make the GUI subsystem a singleton and send it an update directly from the OVRPlayerController (never mind hacking around in 3rdParty code either). Then the GUI decides that some values need to be updated over the network. GUI just calls Network.SendMessage. Right. Forgets about updating the Logic module though. Game goes out of synch.

    These things are terribly, terribly easy to set up with Unity and I'm very happy that finally, everyone is forced to make an informed decision - is it really a good idea if the GUI needs the Network module? Or does it smell like a design flaw?

    While we cannot enforce linkage, we can easily check what links to what. I've written an editor tool that makes a diagram (using graphviz) out of the asmdef references - from time to time I check if there's something fishy about the architecture of the project. Are there any links that should not be?

    Likewise, one can no longer have circular references. These are especially difficult to refactor once they've grown over longer time. For instance, in an older project we have Logic and GUI tightly coupled but on top of that, also the Input module and Postprocessing and Serialization and Animations and VR/Leap stuff and so on. After refactoring the whole project to Assembly Definitions, this "big bunch of files" remains even though logic and GUI really ought to be decoupled. This is a constant source of bugs, either the GUI not being updated properly on Logic/Data changes, or vice versa the GUI resetting values in the Logic module, or worst of all: stackoverflow because Logic and GUI bounce each other messages which is hard to track because it goes through several layers of setters and modifiers and limiters and validity checkers.

    This would not have happened (at least not to this degree where refactoring this would mean redoing most of the app) if we had Assembly Definitions to begin with.

    Therefore, I decree:
    Any decently complex project requires Assembly Definitions to pack code into modules, not for speed but to enforce the app's architecture!
    (also helps to keep developers sane and friendly)
     
  11. nicmarxp

    nicmarxp

    Joined:
    Dec 3, 2017
    Posts:
    341
    Thanks for that insight, but however, is there any way to make Unity do the checks etc faster, so I can start the play mode faster, and not wait 8 seconds each time?

    I thought of getting a better computer, but I have a Macbook Pro Late 2016 which should be ok, it would be kinda silly to buy an iMac Pro for $15.000 and get 7 seconds "compile time" instead. :)
     
  12. mmortall

    mmortall

    Joined:
    Dec 28, 2010
    Posts:
    89
  13. Bill-Sansky

    Bill-Sansky

    Joined:
    Oct 2, 2016
    Posts:
    68
    So far, a careful separation of our scripts in our project under different assemblies showed an increase in compilation time by a factor of 2!! I don't think the gain of speed works if anything it makes compilation much slower in our case.

    It would be great to know what gets recompiled exactly to track down the reason of the slow down :(
     
  14. Sarah_Lee

    Sarah_Lee

    Joined:
    Jul 30, 2015
    Posts:
    6
    We are also very frustrated about the 'overall' compilation time during coding/debugging phase where parent lib must be changed frequently. Though, we really love the ability to compile into separated dll's within Unity.

    Here're some observations:
    1) It appears that (at least on my machine), each asmdef compilation takes minimum of 2 seconds.
    2) Total duration is dependent on number of asmdef compilation per change.

    For example, if we change the 'leaf' asmdef's source files, it compiles in 2 seconds. But, if we change the parent asmdef (and hierarchy requires 8 asmdef recompilation), it will take average of 2*8 = 16 seconds.

    While if we compile everything (without asmdef), it takes average of 4 seconds.

    Asmdef compilation just has too much overhead.
    Really starts to appreciate how Visual Studio enables to compile so quickly.
     
    Gerold_Meisinger likes this.
  15. Bill-Sansky

    Bill-Sansky

    Joined:
    Oct 2, 2016
    Posts:
    68
    I'd like to add that asmdef sometimes totally freeze VS when it has to reload the projects because of code change. When you have many asmdef, it's faster to kill VS and restart it...
     
  16. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    7,563
    Hi,
    I in fact had similar experience. I changed lot of scripts, to adapt and sort, to be suitable for Assembly Definitions, with aim of speeding up the compilation time. Resulted of creating bunch of *.asmdef files (approx 30), for roughly of my 300 scripts. + On top of that, there are 3rd party scripts, which I will revise at some point, if I can put in assembly definitions, if they are not yet done. I will possibly go for further modularation, as I will come back to some scripts, which need future revision.

    However, indeed I haven't noticed any compilation time improvement, for the size of my project. So every little code change, for some references scripts, may take even 22 secs. I was initially upset, on taking attempt of spending time on *.asmdef files. And that is even on SSD drive, along with 3.4GHz CPU. Also, during compilation, there is few seconds, where VS freezes. But it do not stuck for me (Win7).

    Yet, despite no compilation time gain (at least not noticeable), I am happy of reorging scripts into more modular state, removing many cross references. I was very conscious about avoiding cross-references, and making coding modular. But still, I have discovered multiple cases, where I had to rewrite bits of codes, to make suitable for Assembly Definition.

    At the end of the day, every new asset I create from prototype, I put into Assembly Definition. Then import to the main project. This keeps code much more tidy. Also, as mentioned, it become apparent and obvious, which scrip is referenced, by looking at the *.asmdef file.

    One thing I am curious, but not taking an attempt to trying now, is if limiting number of assembly build platforms, to minimum, would help at all. Not doing it now, because every change of *.asmdef, takes some time to recompile.



    Other than that all good, since I wanted project, to be as modular, as possible.
    But no significant time gain on compilation, as was the main goal.
     
    Last edited: Jul 24, 2018
  17. nicmarxp

    nicmarxp

    Joined:
    Dec 3, 2017
    Posts:
    341
    Yes this is about what I discovered. I have only about 40 script files, and it takes 9-10 seconds to compile each time. It's not a huge time, but anything above that is annoying.

    I read something about a burst compiler, has that anything to do with this? It would be awesome if it would be faster to compile, also that it didn't make Unity hang/jerk each time a code was changed...
     
  18. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    There's one way to compile faster it's to put your assets in a folder called Standard Assets (do this only for the scripts of the asset store) or the script you know won't change.
    Secondly if you have in your project settings > editor > sprite packing: enabled in editor. disable that you'll start the game much faster.

    This helped me, maybe it'll help you.
     
  19. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    I noticed the same effect. Compile times got worse after using assembly definitions.
    • 78 script files with 16200 LOCs
      find Assets/Scripts -name '*.cs' -exec cat {} \;|wc -l

    • Processor: i7-7700K 4x4.20Ghz
    • All plugins have been moved to Plugins/
    • To measure the compile time I used the CompileTime.cs script
    no assemblies
    Code (CSharp):
    1.  4.5s changing unrelated Editor script (CompileTime.cs)
    2. 10.5s changing script define symbols in build settings
    3.  5.5s changing loose dependent script (MainLogic.cs)
    4.  5.5s changing heavy dependent script (Utils.cs)
    assemblies
    Code (CSharp):
    1.  4.5s changing unrelated Editor script (CompileTime.cs)
    2. 14.8s changing script define symbols in build settings
    3.  8.3s changing loose dependent script (MainLogic.cs)
    4. 11.2s changing heavy dependent script (Utils.cs)
    All the work restructuring and adapting plugins was good for nothing!
     
    HECer and JimmyCushnie like this.
  20. angularsen

    angularsen

    Joined:
    Apr 22, 2017
    Posts:
    18
    I reduced my recompile time from ~11 seconds to ~6 seconds by introducing assembly definition files, for changes to my core game scripts.

    - Main.dll (my core game stuff, around 40 scripts and all my game specific assets)
    - ThirdParty.dll (all external code and any code I very rarely change myself, tons of scripts and assets but I have no number on it)

    Note that there is no Assembly-Csharp.dll anymore, as recommended by the docs you should make sure all files are covered by assembly definition files to get the full benefit.

    Note also that actual compile time is now very fast, something like 0.5-1 seconds. According to logs the rest of the time is the editor reloading things and that time grows large when you have a lot of assets - not sure if it's only the scripts part of it, or other assets like materials, meshes, scenes etc.
     
    gresolio likes this.
  21. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    @angularsen: Thanks for the hint. I indeed got one useless file in Assembly-Csharp.dll. After deleting it Assembly-Csharp no longer shows up in "solution explorer". However the compile time is still the same.

    This is how I have the project split up (number indicates number of files):
    13 Base
    3 Lib
    8 Misc
    19 Objects
    22 Tutorial
    13 UI

    plus
    Assembly-CSharp-Editor (editor plugins in root)
    Assembly-CSharp-Editor-firstpass (editor plugins in Plugins/)
    Assembly-CSharp-firstpass (all other plugins)

    and 15 assembly definitions of plugins.

    What do you mean by "adding game specific assets to DLLs"?
    And did you add one big assembly definition in the plugins (ThirdParty.dll)? I presumed this is already covered by the legacy behaviour in (Assembly-CSharp-firstpass.dll)?
     
  22. angularsen

    angularsen

    Joined:
    Apr 22, 2017
    Posts:
    18
    I think you should move your Editor files out into a Base/Core lib too, or else they will compile for every change and possibly incur extra editor reload stuff.

    Edit: As a result you should not have any Assembly-Csharp assemblies at all.
     
  23. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    4,243
  24. angularsen

    angularsen

    Joined:
    Apr 22, 2017
    Posts:
    18
    > What do you mean by "adding game specific assets to DLLs"?
    I meant adding assembly definition files to move game specific scripts to DLLs, sorry for being unclear.

    > And did you add one big assembly definition in the plugins (ThirdParty.dll)? I presumed this is already covered by the legacy behaviour in (Assembly-CSharp-firstpass.dll)?
    Yes I did. I started splitting up into one for Oculus and one for TextMeshPro etc, but I figured that complexity didn't give me anything but extra maintenance. I only touch those when updating the packages and at that point a full rebuild is fine.
     
  25. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    Thanks for the script, but there is something funny going on.
    If I do a full recompile (script define symbol change) all the assembly build times add up to 35s whereas the compile time script reports 14s. If I just change an editor script all the build times add up to 3.5s whereas the compile time script reports 7.5s. Using a manual stopwatch matches the compile time script reported times.
     
  26. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    4,243
    I imagine there is more than just the compilation being counted. For example, my script does not count the assembly reload.

    Try hooking into that event and adding the timing to it. I think that should add the missing seconds.
    https://docs.unity3d.com/ScriptReference/AssemblyReloadEvents.html

    You will need to store the time in Editorprefs or something like that as data will be lost between the reload.
     
  27. angularsen

    angularsen

    Joined:
    Apr 22, 2017
    Posts:
    18
    I believe the Unity log spits out some duration numbers after compile when it reloads stuff, and yes, this seems to take up a majority of the time. I assume assembly reloading and possibly updating the editor with new inspector panels etc. I wish there was more information on what is taking up all this time, because compilation itself is often only a small piece of it.

    Edit: I read somewhere that when the spinner in the lower right is spinning, then it is compiling, and when it stops spinning and the editor hangs for several seconds, that's when it is reloading stuff.
     
  28. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    4,243
  29. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    4,243
    Yes assembly reload can take up quite a bit of time but also any editor scripts with InitializeOnLoad will need to be started up again which can cause significant delays when using some assets.
     
  30. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    The compilation times cannot be right because a full recompile (script define symbol change) takes twice as long in total as the actual measured time (35s reported, 14s actual measured time).
    Assembly reload takes about 4s in every case.
     
  31. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    4,243
    Have you tried the profiler in Editor mode? It sounds like there is more than just script recompilation slowing things down.
     
  32. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    @angularsen: Thanks for the ThirdParty.dll hint. I put everything under plugins in one asmdef. It's now much simpler to handle and cleaner to look at. All Assembly-CSharp (including firstpass X Editor) are gone. Times are now somewhere near no-asmdefs, but still bit worse.
    Code (csharp):
    1.  4.5s changing unrelated Editor script (CompileTime.cs)
    2. 11.0s changing script define symbols in build settings
    3.  5.7s changing loose dependent script (MainLogic.cs)
    4.  8.3s changing heavy dependent script (Utils.cs)
    @karl_jones: Profiler looks fine, everything is below 5ms except for a 3000ms spike on assembly reload. Still I think there is a bug in the compilation time calculation because it's larger than the time measured with a manual stop watch.
     
  33. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    no assemblies changing heavy dependent script
    1.04s Assembly-CSharp.dll
    0.86s Assembly-CSharp-Editor.dll
    compilation total: 1.89s
    reload assemblies: 3.34s

    with assemblies changing heavy dependent script
    0.80s Lib.dll
    0.98s Objects.dll
    0.81s Tutorial.dll
    0.90s UI.dll
    0.93s Base.dll
    0.70s Editor.dll
    compilation total: 5.11s
    reload assemblies: 3.14s

    I agree with @Sarah_Lee and guess there is a minimum overhead for compiling an assembly which sums up when using too many assemblies compared to the (still too small) compile time of the overall project and the time needed for reloading assemblies anyway.
     
    Last edited: Sep 12, 2018
  34. Gerold_Meisinger

    Gerold_Meisinger

    Joined:
    Sep 8, 2015
    Posts:
    93
    Here is my adapted assembly debugger script:
    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4. using UnityEditor;
    5. using UnityEditor.Compilation;
    6.  
    7. [InitializeOnLoad]
    8. public class AsmdefDebug
    9. {
    10.     const string RELOAD_TIME_KEY = "AssemblyReloadEventsTime";
    11.  
    12.     static Dictionary<string, DateTime> compilationStartTimes = new Dictionary<string, DateTime>();
    13.     static double compilationTotalTime;
    14.  
    15.     static AsmdefDebug()
    16.     {
    17.         CompilationPipeline .assemblyCompilationStarted  += OnCompilationStarted;
    18.         CompilationPipeline .assemblyCompilationFinished += OnCompilationFinished;
    19.         AssemblyReloadEvents.beforeAssemblyReload        += OnBeforeReload;
    20.         AssemblyReloadEvents.afterAssemblyReload         += OnAfterReload;
    21.     }
    22.  
    23.     static void OnCompilationStarted( string obj )
    24.     {
    25.         compilationStartTimes[obj] = DateTime.UtcNow;
    26.     }
    27.  
    28.     static void OnCompilationFinished( string assembly, CompilerMessage[] msgs )
    29.     {
    30.         int pathStrLen = "Library/ScriptAssemblies/".Length;
    31.         var timeSpan = DateTime.UtcNow - compilationStartTimes[assembly];
    32.         compilationTotalTime += timeSpan.TotalMilliseconds;
    33.         UnityEngine.Debug.LogFormat( "{0:0.00}s {1} compile", timeSpan.TotalMilliseconds / 1000f, assembly.Substring( pathStrLen, assembly.Length - pathStrLen ) );
    34.     }
    35.  
    36.     static void OnBeforeReload()
    37.     {
    38.         UnityEngine.Debug.LogFormat( "compilation total: {0:0.00}s", compilationTotalTime / 1000f );
    39.         EditorPrefs.SetString( RELOAD_TIME_KEY, DateTime.UtcNow.ToBinary().ToString() );
    40.     }
    41.  
    42.     static void OnAfterReload()
    43.     {
    44.         var dateBinStr = EditorPrefs.GetString( RELOAD_TIME_KEY );
    45.         long dateBin = 0;
    46.         if( long.TryParse( dateBinStr, out dateBin ) )
    47.         {
    48.             var date     = DateTime.FromBinary( dateBin );
    49.             var timeSpan = DateTime.UtcNow - date;
    50.             UnityEngine.Debug.LogFormat( "reload assemblies: {0:0.00}s", (float)timeSpan.TotalMilliseconds / 1000f );
    51.         }
    52.        EditorPrefs.DeleteKey( RELOAD_TIME_KEY );
    53.     }
    54. }
    55.  
    I would recommend running it before doing any asmdef restructuring and check if your Assembly-CSharp compile time is significantly higher (like five times higher) than the compile time for an empty asmdef. Otherwise your average change will have too much overhead instead being of any use and you wasted a lot of time restructuring.
     
  35. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
  36. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    7,563
    dll are best options in terms of editor performance and compilation time.
    Only down side of dlls is, you can not edit its content from Unity.
    Other than that dlls are much better of assembly file, providing, you don't need edit its content.
     
    FeastSC2 likes this.
  37. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    Alright, I made assembly definitions for my whole project.

    My compilation went from 13sec to 8.5sec/34sec (best case (1script alone with no dependencies) - worst case).
    Moving files can take up to 60s...

    The really apparent problem is that the time needed to reload the assemblies does not change, reloading assemblies takes more time the more scripts you have in your project and using assembly definitions does not change this.

    Unity_2018-12-28_16-34-10.png


    EDIT:
    Now that my project is structured into assemblies I can attempt to make DLL's at least.

    I'm using Visual Studio, so far the biggest hurdle I have with DLL's is that I must manually add references to the Library and that gets quickly tedious. Especially because I have dependencies on OdinInspector and other libraries like TextMeshPro... and that I would have around 30 libraries.

    Unity automatically updates those references when using assembly definitions. Is there a way that I could have a similar behaviour with C# Libraries/DLL's?
     
    Last edited: Dec 28, 2018
    Antypodish likes this.
  38. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    892
    Looking back on it, there are just too many cons to making DLL's:

    1) Will lose all the references to the scripts in the project. (And after doing this, you won't be able to change the name of your classes afterwards).
    2) Cannot use any unity preprocessor directives (#IF UNITY_EDITOR, ...) in libraries.
    3) References to libraries must be updated every time you change the version of Unity or when you want to rely on some asset of the asset store.

    I think the best option for me is to remove the assembly definitions at this stage and go with the vanilla unity structure. I personally don't care about structuring my code all I wanted was faster compilation time and that's just not possible without strong hindrances it seems.

    I hope the unity guys make this slow compiling a thing of the past at some point.
     
  39. kenvink

    kenvink

    Joined:
    Sep 13, 2017
    Posts:
    15
    And If I want to have Unity Test, I have to use Custom Assembly Definitions to split the project into multiple dlls.
    I do not understand why Unity cannot support:
    Test Assembly references Predefined Assemblies (Assembly-CSharp.dll or Assembly-CSharpEditor.dll)
    That looks like simple/lightweight options for developer to start with.

    The problem with Custom Assembly Definition is:
    It does not automatically separate editor/non-editor scripts into different Assemblies. So the moment I start to use Custom Assembly Definition I need to re-organize entire project's scripts (including 3rd party scripts) into to non-editor script/editor script folders...and that ends up with a lot of Custom Assembly Definitions/Links to maintain plus the all sort of issues in FeastSC2's post above.

    I understand that everything has pros and cons.
    But is this Custom Assembly Definitions worth the cost to enable other things: Unity Test, compilation time, architecture..?
     
  40. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    677
    So I am looking at this thread today, with Unity's incremental compiler integrated into 2018.3 and my pretty careful use of assembly definition, I am still seeing pretty long compile time and slower reload time due to number of assembly definitions (about 30 assemblies, mainly from unity packages, some from asset store plugins, and a few from my own code).

    Here I am, changing a single file, which cause a single assembly to recompile, which only contains about 20 files, on a Macbook Pro 13'' early 2015 (2.7 GHz Intel Core i5):

    Screen Shot 2019-03-22 at 14.03.06.png

    I am not sure this is normal, I am using Gerold Meisinger's script from above. Can anyone share their benchmark nowadays?

    EDIT: while we are at it, here is how long Unity takes to enter play mode just reloading assemblies. I don't know if it would be faster or slower without the assemblies, but since most of them are from packages, I don't really have a choice. (If someone manages to get that sweet 0.5 second reload Unity team was going for, please let us know.)

    Screen Shot 2019-03-22 at 14.28.23.png

    Here is the time for any changes that triggers a full compile (like adding a assembly definition, moving a definition, changing references on a definition...)

    Screen Shot 2019-03-22 at 16.09.17.png
     
    Last edited: Mar 22, 2019
  41. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    Hi. Thanks for this thread. After spending a day messing about with asm defs i am about 2s compilation, 14s assembly reload! Does anyone know where to get detailed information on this process please. What does it actually do?
     
  42. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    So, for fun i tried loading an empty scene and testing again. Compilation time for a file in a ''mid level" assembly remains 2 seconds but assembly reload dropped to 5. So the contents of the active scene definitely makes a difference. Apologies if this is already well known but looking at forum posts there does seem to be a blurring between 'compilation time' and 'assembly reload time'. Most posts / discussions seem to consider them together, i.e. "when i change a script, how long does unity freeze for?"
     
  43. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    7,563
    Is no "blurring". But is well known issue for many (not everyone), where gained compilation time, doesn't justified increased time, for every script change.

    As the result loosing, not gaining proficiency.
     
  44. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    109
    Hey there!

    Joining the gang to complain about very slow "Assembly Reload Time".
    Here is my benchmark:



    Now, after having moved things into the `Standard Assets` folder, I get less stuff compiling but that's all thrown out of the window if I keep on having ~8s of reload time for absolutely any tiny change.

    I also went through and removed lots of `[InitializeOnLoad]` but still the same.

    What can be done for this?
     
  45. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    I did a fair amount of looking into this and I did manage to get the time down a bit. There was not one single problem but lots of cumulative slow down. Assembly definitions may help if you have many scripts but for me the solution was to simplify my scene and load certain heavy objects as prefabs at runtime. Even inactive gameobjects can contribute. Vegetation studio and gaia although both excellent tools sometimes seemed to eat a little time. Closing Editor windows e.g. asset store and preferences also helped. Good luck!
     
    andreiagmu likes this.
  46. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    109
    @jamespaterson I see. Is there any script or tool that I can use to find more precisely what is eating that time?

    Having something saying "hey, package X is taking 0.5s to activate" would help me immensely, I can't just go through everything and A/B test for tiny bits of improvement.
     
  47. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    Unfortunately this is essentially what i ended up doing. You can enable profiling of the editor, press pause and then start, then quickly pause again to catch the "starting" phase and interrogate that which may be helpful. This article was helpful:

    https://medium.com/@lynxelia/unity-...time-it-takes-to-enter-play-mode-fd07b43c1daa

    I deployed some of the techniques e.g. forcing garbage collection which was informative but didn't really solve the problem per-se. There were a few different things which helped as per above but the primary solution really was to clean out the scene to the bare bones and load on startup.
     
    andreiagmu likes this.
  48. neshius108

    neshius108

    Joined:
    Nov 19, 2015
    Posts:
    109
    I tried doing that but even with deep profiling, the compilation/refresh part isn't being recorded.

    My next step is to try disabling the editor.log, I'm sure some packages I have might be slowing some things down but it's really hard to disable them temporarily when I use them in my codebase.

    UPDATE:

    For future readers, after lots of tests, here is what I did to manage to go from 9-10s to 6-7s in the compile/reload times:

    1. Moved imported assets and general tools into the "Standard Assets" folder (name has to be that)
    2. Removed as many files as possible (I went through and deleted all the Docs/Example/Demo folders from the assets I was using), their size is not necessarily important
    3. Removed default packages which I didn't need: Ads, IAP, Analytics, Multiplayer, XR Legacy, Memory Profiler (you can always bring them back whenever you actually need them)

    Notes: if, for some crazy reason, someone doesn't use the attach debugger feature in VS-Unity, disabling the "Editor Attaching" from the preferences, actually makes the reloading quicker (about 0.3-0.5s for me).

    Other crazy stuff I found:

    Unity seems to spam registry calls for certain player prefs, if they are not found, it will still try and try and try. Using process monitor, you can actually find the key and create an empty one in the registry. Little bit of a hack but worked and it stopped wasting time there.

    As a side note: it turns out Unity loads the verdana(b) fonts every single compilation, it only takes 0.003s but yeah it adds up :p

    And now, I can finally go back to develop in peace :rolleyes:

    upload_2019-5-8_1-11-39.png

    EDIT: Posted a little tutorial/post about the adventure: https://gamejolt.com/games/talesofk...attempting-to-decrease-compile-times-she9y7qf
     
    Last edited: May 8, 2019
  49. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    Thanks for posting details of your investigation. Very helpful. I would not be too down on the timesaving you achieved. Every second helps
     
  50. jamespaterson

    jamespaterson

    Joined:
    Jun 19, 2018
    Posts:
    287
    Looks like unity are taking this issue seriously and are proposing some options to improve matters in 2019.3:

    https://docs.google.com/document/d/1QFMWHG05w7Rj8pe2nz5rbWUm1gj-Pd9M71Uz9dc-dg4/mobilebasic

    This makes for an interesting read and supports the notion that scene complexity is a significant contributor to "entering playmode" time i think. It seems perverse that "loading on demand after entering playmode" is potentially faster than "already having in the scene" but there you go...
     
    SugoiDev likes this.
unityunity