LuaTable.GetValue without GC

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
alfonso
Posts: 104
Joined: Mon Jul 13, 2015 6:31 am

LuaTable.GetValue without GC

Post by alfonso »

Hi Tony!,

I started recently with the optimization in the serialized system of the game, but i noticed that when I loop over the conversations to gets the values it's generate a lot of GC when i use GetValue over a LuaTable.

What is the best way to get a value without generete any GC or less if it is possible?

Thanks for all :)

Image

Image
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: LuaTable.GetValue without GC

Post by Tony Li »

Hi Alfonso,

Try the code below. It should generate almost zero garbage. It uses LuaInterpreter (Language.Lua) directly, and it runs the enumerator manually instead of using foreach, which can cause garbage collection due to boxing. I used the "Title" field in the example below because my test database didn't have a Count field.

Code: Select all

public void RunTest()
{
    var sb = new StringBuilder();

    // Get the Conversation[] table straight from the Lua environment:
    var conversationTable = Lua.Environment.GetValue("Conversation") as Language.Lua.LuaTable;

    // Loop through the table's list elements:
    // (Enumerate manually to avoid garbage)
    int idInList = 0;
    var conversationListEnumerator = conversationTable.ListValues.GetEnumerator();
    while (conversationListEnumerator.MoveNext())
    {
        idInList++;
        var fieldTable = conversationListEnumerator.Current.Value as Language.Lua.LuaTable;
        ProcessConversation(sb, idInList, fieldTable);
    }

    // Loop through the table's dictionary elements:
    // (Enumerate manually to avoid garbage)
    var conversationDictEnumerator = conversationTable.KeyValuePairs.GetEnumerator();
    while (conversationDictEnumerator.MoveNext())
    {
        var idKey = conversationDictEnumerator.Current.Key;
        var idInDict = (int)(idKey as Language.Lua.LuaNumber).Number;
        var fieldTable = conversationDictEnumerator.Current.Value as Language.Lua.LuaTable;
        ProcessConversation(sb, idInDict, fieldTable);
    }

    Debug.Log(sb.ToString());
}

void ProcessConversation(StringBuilder sb, int id, Language.Lua.LuaTable fieldTable)
{
    var enumerator = fieldTable.KeyValuePairs.GetEnumerator();
    while (enumerator.MoveNext())
    {
        var key = enumerator.Current.Key as Language.Lua.LuaString;
        if (string.Equals(key.Text, "Title"))
        {
           var value = enumerator.Current.Value as Language.Lua.LuaString;
            sb.AppendFormat("Conversation[{0}].Title = '{1}'; ", id, value.Text);
            break;
        }
    }
}
The way LuaInterpreter handles tables is a little confusing. If you add elements Conversation[1], Conversation[2], Conversation[3], in order, LuaTable will store them in a List for efficiency. But if you skip numbers -- Conversation[1], Conversation[4], Conversation[7] -- it can't store them in a list, so it stores the new elements in a Dictionary. But the old elements are still in the List. That's why the code above has to loop through the List and the Dictionary.
alfonso
Posts: 104
Joined: Mon Jul 13, 2015 6:31 am

Re: LuaTable.GetValue without GC

Post by alfonso »

Thanks mate i will try them :)
alfonso
Posts: 104
Joined: Mon Jul 13, 2015 6:31 am

Re: LuaTable.GetValue without GC

Post by alfonso »

Image
this is another thing :) thanks so much men!!!
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: LuaTable.GetValue without GC

Post by Tony Li »

Happy to help!
Post Reply