Author Topic: What is BetterList?  (Read 11772 times)

Disastercake

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 1
  • Posts: 87
  • www.disastercake.com
    • View Profile
    • Disastercake
What is BetterList?
« on: August 05, 2012, 04:50:23 PM »
I saw in the recent update:

Quote
- FIX: Replaced most usages of List with BetterList instead in order to significantly reduce memory allocation.

What exactly is BetterList?  A google search does not seem to find any relevant information for me.
Creator of Soul Saga.
http://www.disastercake.com

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is BetterList?
« Reply #1 on: August 05, 2012, 06:35:53 PM »
It's a class I wrote in NGUI. Every time you add an item to a regular List, it re-allocates a new array. This is terrible for performance and garbage collection. Same thing happens when you remove items. BetterList doesn't do this, and behaves more like std::vector, if you're familiar with C++ -- it grows its size only when necessary, and does so in chunks, rather than 1 by 1.

maul

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: What is BetterList?
« Reply #2 on: February 15, 2014, 06:25:55 AM »
Hi! Is this still the case? I don't know a lot about .NET and mono internals, but it would seem ridiculous for List to allocate memory item-by-item and to throw away the internal array on Clear().

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is BetterList?
« Reply #3 on: February 16, 2014, 02:05:20 AM »
Unity hasn't updated their version of mono in many years, so yes, it's still true.

junkier

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: What is BetterList?
« Reply #4 on: March 28, 2014, 06:24:40 AM »
Every time you add an item to a regular List, it re-allocates a new array. This is terrible for performance and garbage collection. Same thing happens when you remove items.
Unity hasn't updated their version of mono in many years, so yes, it's still true.

Hi there!
I was very surprised when I have seen BetterList class. And I was wondering, why System.Collections.Generic.List is so bad, and came there to find answer.
I've performed simple test in Unity Editor (Unity 4.3.4, Unity 3.5 .net full Base Class Libraries), that has shown, as I expected, that System.Collections.Generic.List works well, as expected, with memory.
Please see my example code below:

using System.Collections.Generic;

var list = new List<int>();
Debug.Log("Initial capacity: " + list.Capacity);
for (int i = 0; i < 10; ++i)
{
  list.Add(i);
  Debug.Log(string.Format("Added element '{0}'. Current capacity = {1}", i, list.Capacity));
}

list.Clear();
Debug.Log("List capacity after clear: " + list.Capacity);

// Filling list for second time
for (int i = 0; i < 10; ++i)
{
  list.Add(i);
  Debug.Log(string.Format("Added element '{0}'. Current capacity = {1}", i, list.Capacity));
}

list.Clear();
Debug.Log("List capacity after clear: " + list.Capacity);

And the result:

Quote
Initial capacity: 0
Added element '0'. Current capacity = 4
Added element '1'. Current capacity = 4
Added element '2'. Current capacity = 4
Added element '3'. Current capacity = 4
Added element '4'. Current capacity = 8
Added element '5'. Current capacity = 8
Added element '6'. Current capacity = 8
Added element '7'. Current capacity = 8
Added element '8'. Current capacity = 16
Added element '9'. Current capacity = 16
List capacity after clear: 16
Added element '0'. Current capacity = 16
Added element '1'. Current capacity = 16
Added element '2'. Current capacity = 16
Added element '3'. Current capacity = 16
Added element '4'. Current capacity = 16
Added element '5'. Current capacity = 16
Added element '6'. Current capacity = 16
Added element '7'. Current capacity = 16
Added element '8'. Current capacity = 16
Added element '9'. Current capacity = 16
List capacity after clear: 16

So, as we can see, new array allocated only when we trying to add more elements than capacity allows. If you know beforehand how much elements you are going to have in a list, you can pass this number to List's constructor, and it will allocate in memory array with corresponsind size.
All what I'm trying to say, that now System.Collections.Generic.List is working in Unity just like MSDN says (at least for .NET 3.5).


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: What is BetterList?
« Reply #5 on: March 28, 2014, 08:45:46 AM »
In my test I had 2 lists -- one list always pre-allocated with 1 million integers, and a second list which iterated through the first and added the integers to the 2nd list one at a time. At the end of the for loop it would Clear() the second list, so the next frame the process would repeat again.

I monitored performance via a stopwatch as well as GC collection / spikes in the profiler window. FWIW my test was done back in Unity 3.4 days.