Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Good practice with List & Class dynamic creation

Discussion in 'Programming Questions and Suggestions' started by BobbySix, Jan 15, 2019.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. BobbySix Trainee Engineer

    Messages:
    32
    Hi everyone,

    I have some very general questions about Classes created in a function, but maybe the InGame compiler has some specifity to know.

    In the order :
    1 -> Is there any interest for performance to call a global variable instead of create a local one in a function ?
    2 -> And for a class, any interest to always rewrite a global one for performance ?
    3 -> About dynamic creation of a class in a function, any risk of memory leak or compiler release local data after function execution ?
    4 -> About List ? Same behavior that any class or some specificities to know ?


    Here an exemple of function where I need a very fast treatment and no possibility of memory leak.

    Code:
    void AddItemOnList(IMyInventoryItem TestItem)
    { // this function could be called many time (as many as items slot in a grid)
    	c_Tag ItemTag = TagForThisItem(TestItem); //is it better to use a global data  ?
    	List<c_Item> List = __AllItems[ItemTag.NativeTag]; //and for a list ?
    	if (List.Exists(c => c.Name == TestItem.Content.SubtypeId.ToString())) 
    		List.Find(c => c.Name == TestItem.Content.SubtypeId.ToString()).AddAmount((long)TestItem.Amount); 
    	else
    		List.Add(new c_Item(TestItem.Content.SubtypeId.ToString(), (long)TestItem.Amount));
    }
     
  2. Malware Master Engineer

    Messages:
    9,428
    Yes, doing lots of allocations will make the garbage collector sad. Avoid allocation for often run code. This - unfortunately - includes ToString (normally). I seem to remember that the ToString for a SubtypeId is fine though...

    Reuse where you can.
     
  3. BobbySix Trainee Engineer

    Messages:
    32
    I just see that SubTypeId is a VRage.Utils.MyStringHash with a property soberly named "String"
    I will try this ^^
     
  4. BobbySix Trainee Engineer

    Messages:
    32
    In all my function with multiple iteration I switch all local data/class, by multiple reset and using of global data/class.

    I have a "counter of operation" in the concerned script (Runtime.CurrentInstructionCount)
    He slightly increased with the new programmation but never pass 6000 instructions in my test grid (50 000 is the max allowed), but nothing really problematic.

    However I still have a problem who seems to be linked with the complexity and the number of iteration of my script.
    After few minutes running I start to have difficulty to jump on the grid where the script run.
    I don't see any problem on the perf console, no lag, absolutely no problem to jump and run and dance on other grids, but an overtime increased diffculty to keep my feet on the grid where the script run.

    Anybody has already experience that kind of problem ?
     
  5. BobbySix Trainee Engineer

    Messages:
    32
    Maybe find the problem.
    Apparently operating directly on string on C# is costly, will try with stringbuilder.
     
  6. BobbySix Trainee Engineer

    Messages:
    32
    I convert most of my strings to stringbuilder, but for one strongly iterate operation (used for LCD scrolling), I'm not sure to which is the best way.

    Code:
    public class c_PrintedLCD
    {
    private int ScrollIndex = 0;
    public StringBuilder Content = new StringBuilder(5000);
    private StringBuilder AffContent = new StringBuilder(5000);
    private StringBuilder TmpStrBld = new StringBuilder(500);
    public IMyTextPanel LCD;
    
    public void Print()
    {
    	if (ScrollIndex > Content.Length || Content.Length <= MAXLCDCHAR)
    	{
    		ScrollIndex = 0;
    		LCD.WriteText(this.Content, false);
    	}
    	else
    	{
    	AffContent.Clear(); TmpStrBld.Clear();
    	AffContent.Append(Content);
    
    	//1st way -> handle with a third StringBuilder and use "AppendSubstring" function
    	TmpStrBld.AppendSubstring(Content, ScrollIndex, AffContent.Length - ScrollIndex);
    	LCD.WriteText(AffContent.Insert(0, TmpStrBld));
    
    	//2nd way -> cast a string directly
    	string x = Content.ToString(ScrollIndex, AffContent.Length - ScrollIndex);
    	LCD.WriteText(AffContent.Insert(0, x));
    	}
    	ScrollIndex += MAXLINECHAR;
    }		 
    }
    To avoid using a string I write ugly code with a third temp stringbuilder, hoping "AppendSubstring" don't have an internal string allocation.
    Is is really useful ? I doubt.
     
Thread Status:
This last post in this thread was made more than 31 days old.