Logo
  • Assets
  • Contact
  • About
  • Forums
  • Login

GC related performance issues

Forums › 💬 NodeCanvas › ⚙️ Support › GC related performance issues

  • This topic has 0 replies, 2 voices, and was last updated 9 years, 11 months ago by Gavalakis.
Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • May 17, 2016 at 11:17 am #18625
    frostbyte
    Participant

      Hello,

      we are experiencing a lot of per-frame allocations (mostly due to LINQ usage). These can be a big problem on mobiles and can easily be sorted out. I provide an example fix that we did on our side, but it would be nice to see this in one of the next NodeCanvas releases:

      OnCheck used to be like this, allocating about 3kb per frame and the GC wasn’t happy. Also ToArray() is not GC-friendly either.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
       
      protected override bool OnCheck() {
      var args = parameters.Select(p => p.value).ToArray();
       
      if (checkValue.varType == typeof(float))
      return OperationTools.Compare( (float)targetMethod.Invoke(agent, args), (float)checkValue.value, comparison, 0.05f );
      if (checkValue.varType == typeof(int))
      return OperationTools.Compare( (int)targetMethod.Invoke(agent, args), (int)checkValue.value, comparison );
      return object.Equals(targetMethod.Invoke(agent, paramList), checkValue.value);
      }
       

      The solution would be to have a fixed size array for this as such:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
       
      private object[] paramList;
      protected override bool OnCheck() {
       
      // A more efficient way of doing this
      if (paramList == null) {
      paramList = new object[parameters.Count];
      }
       
      for (int i = 0; i < parameters.Count; i++) {
      paramList [ i ] = parameters [ i ].value;
      }
       
      if (checkValue.varType == typeof(float))
      return OperationTools.Compare( (float)targetMethod.Invoke(agent, paramList), (float)checkValue.value, comparison, 0.05f );
      if (checkValue.varType == typeof(int))
      return OperationTools.Compare( (int)targetMethod.Invoke(agent, paramList), (int)checkValue.value, comparison );
      return object.Equals(targetMethod.Invoke(agent, paramList), checkValue.value);
      }
       

      This got rid of the allocations and also the spikes in the profiler.

      LINQ is very useful, however not to be used in potentially performance intensive situations or on weak hardware.

      Thanks!

      May 19, 2016 at 4:18 pm #18626
      Gavalakis
      Keymaster

        Hello,

        Thanks a lot for the improvement code 🙂
        I’ve just included this for the next version and will also check for other linq replacements where performance is key as well.

        Thanks again!

      • Author
        Posts
      Viewing 2 posts - 1 through 2 (of 2 total)
      • You must be logged in to reply to this topic.
      Log In

      Footer Logo

      Home | Contact | Privacy Policy
      Twitter | Discord | YouTube
      Paradox Notion

      • Login
      • Register
      Forgot Password?
      Lost your password? Please enter your username or email address. You will receive a link to create a new password via email.
      body::-webkit-scrollbar { width: 7px; } body::-webkit-scrollbar-track { border-radius: 10px; background: #f0f0f0; } body::-webkit-scrollbar-thumb { border-radius: 50px; background: #dfdbdb }