Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

C# Compiler Holy moly! Alloc appreciation thread

Discussion in 'Experimental Scripting Previews' started by Baste, Jul 23, 2016.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,199
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public class Test : MonoBehaviour {
    5.  
    6.     public int[] ints = {1, 2, 3};
    7.     public List<int> instList = new List<int> {1, 2, 3};
    8.     public int sum;
    9.  
    10.     private void Update() {
    11.         //5.3.6.p1:                         0 alloc
    12.         //5.3.5.p8-csharp-compiler-upgrade: 0 alloc
    13.         foreach (var i in ints) {
    14.             sum += i;
    15.         }
    16.  
    17.         //5.3.6.p1:                         40B alloc
    18.         //5.3.5.p8-csharp-compiler-upgrade: 0   alloc!
    19.         foreach (var i in instList) {
    20.             sum += i;
    21.         }
    22.     }
    23. }
    Welcome to the future!
     
    PhilSA, image28 and invisiblesanta like this.
  2. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    ABOUT FRICKIN' TIME!

    Meanwhile, in a secret Unity Technologies lab, they can now allocate their resources to easier things - like making pigs fly.
     
  3. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,533
    It's the future, only on a different timeline, the 5.3 timeline that is.
     
  4. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    One of our biggest goals with the Mono upgrade is it come up with a plan to keep Unity up to date with the rest of the .NET ecosystem. We have a big hurdle to get past with this initial upgrade, but once that is clear, we don't plan to fall behind again.
     
  5. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    Will this be part of the 5.5 beta from the start then?
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    @orb

    Yes, the new C# compiler is in the closed 5.5 alpha now. Barring any major problems (we haven't seen any yet), it will be in the 5.5 beta and the 5.5 release.
     
    kB11, Deleted User, Peter77 and 4 others like this.
  7. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
     
  8. unormal

    unormal

    Joined:
    Jan 10, 2012
    Posts:
    65
     
  9. Vanamerax

    Vanamerax

    Joined:
    Jan 12, 2012
    Posts:
    937
    Thank you!
     
  10. jctz

    jctz

    Joined:
    Aug 14, 2013
    Posts:
    47
    Orb, your profile pic is most disturbing I've ever seen.

    That is all.
     
    orb likes this.
  11. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,199
    @JoshPeterson, I just ran a test build of World To The West with the 5.3.8 version. It's about 1-2 hour worth of gameplay in about 30ish scenes, and everything worked perfectly. No bugs! Or, well, no bugs that wasn't already there.
     
    fantastisch_ likes this.
  12. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    @Baste

    Excellent! Thanks for testing this, I really appreciate it!
     
  13. Onsterion

    Onsterion

    Joined:
    Feb 21, 2014
    Posts:
    215
    Great news!
     
  14. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Does anyone know if this stops the Dictionary GC alloc with an enum TKey? I would guess not, since it still needs to be boxed for IsEquals, but I'd love to be wrong.
     
  15. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    @Ferazel

    I don't think this change prevents an allocation in this case. But we've found that sometimes these things can be subtle and are often very sensitive to the code involved. Can you provide some specific example code that allocates with the older Mono compiler? We can try it with the new one to see for sure.
     
  16. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    Thanks for your interest @JoshPeterson

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class DictionaryAlloc : MonoBehaviour
    7. {
    8.     public enum TimeZones
    9.     {
    10.         EST,
    11.         EDT
    12.     }
    13.  
    14.     private Dictionary<TimeZones, float> m_allocDictionary = new Dictionary<TimeZones, float>();
    15.  
    16.     private Dictionary<TimeZones, float> m_noAllocDictionary = new Dictionary<TimeZones, float>(new TimeZoneEnumCompare());
    17.     private class TimeZoneEnumCompare : IEqualityComparer<TimeZones>
    18.     {
    19.         public bool Equals(TimeZones a, TimeZones b)
    20.         {
    21.             return (int)a == (int)b;
    22.         }
    23.  
    24.         public int GetHashCode(TimeZones a)
    25.         {
    26.             return (int)a;
    27.         }
    28.     }
    29.  
    30.     private float m_dummyMath = 0;
    31.     private float m_curVal = 0;
    32.     private bool m_allocMode = true;
    33.  
    34.     void Start ()
    35.     {
    36.         m_allocDictionary.Add(TimeZones.EST, 1);
    37.         m_allocDictionary.Add(TimeZones.EDT, 2);
    38.         m_noAllocDictionary.Add(TimeZones.EST, 1);
    39.         m_noAllocDictionary.Add(TimeZones.EDT, 2);
    40.     }
    41.  
    42.     void Update ()
    43.     {
    44.         if(Input.GetKeyDown(KeyCode.Space))
    45.         {
    46.             m_allocMode = !m_allocMode;
    47.         }
    48.  
    49.         if(m_allocMode)
    50.         {
    51.             AccessAllocDictionary();
    52.         }
    53.         else
    54.         {
    55.             AccessNoAllocDictionary();
    56.         }
    57.     }
    58.  
    59.     private void AccessAllocDictionary()
    60.     {
    61.         // ContainsKey is 60B Editor/Standalone GCAlloc
    62.         if (m_allocDictionary.ContainsKey(TimeZones.EST))
    63.         {
    64.             m_dummyMath += 1;
    65.         }
    66.  
    67.         // Direct access is 60B Editor/Standalone GC Alloc
    68.         m_dummyMath += m_allocDictionary[TimeZones.EDT];
    69.  
    70.         // TryGetValue is 60B Editor/Standalone GC Alloc
    71.         if (m_allocDictionary.TryGetValue(TimeZones.EDT, out m_curVal))
    72.         {
    73.             m_dummyMath += m_curVal;
    74.         }
    75.     }
    76.  
    77.     // After writing a comparator dictionary they no longer alloc
    78.     private void AccessNoAllocDictionary()
    79.     {
    80.         if (m_noAllocDictionary.ContainsKey(TimeZones.EST))
    81.         {
    82.             m_dummyMath += 1;
    83.         }
    84.  
    85.         m_dummyMath += m_noAllocDictionary[TimeZones.EDT];
    86.  
    87.         if (m_noAllocDictionary.TryGetValue(TimeZones.EDT, out m_curVal))
    88.         {
    89.             m_dummyMath += m_curVal;
    90.         }
    91.     }
    92. }
    93.  
    I'd really like to not be penalized for every enum dictionary/hash by needing to write an IEqualityComparer class object. If this could be done auto-magically it would be super.
     
    Last edited: Aug 25, 2016
  17. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    @Ferazel

    Thanks, I'll have a look at this soon.

    Initially, I suspect that it will still allocate, as the new C# compiler from Mono isn't quite as good with enums in cases like this as Roslyn is. But I could be wrong.

    Out of curiosity, how are you determining that GC allocations are occurring this case? I'm interested to know your testing methodology.
     
  18. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,775
    @Ferazel

    The IL code generated by the C# compiler for the Update method in this example is the same with the old and new compiler, so I would not expect the allocation behavior to change.
     
  19. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    513
    @JoshPeterson I ran the Unity profiler on both editor and standalone with this script attached to the main camera I didn't look at the IL. Thank you very much for testing it though. I still look forward to being able to use foreach again.
     
    JoshPeterson likes this.