Jump to content
Sign in to follow this  
Wandering Soulstar

Memory Use (Next Question)

Recommended Posts

Good afternoon all,

Have been coding away for a couple of weeks, and when finally bringing it inworld I realized that even in Mono I need to remember about memory usage when it comes to coding. Now apart from pulling my hair out trying to figure where I could fix things the most with the least amount of effort, I was looking at one general coding quirk of mine to see what overhead that might be causing. The quirk is that I like to code with Psuedo-Constants (knowing that LSL does not allow the definition of real constants), i.e rather than using literals like "button name" in my code I'll have a global called BUTTON_NAME. Now in a real coding language that, from what I remember, is good practice, and I remember back in the days of LSO coding there were situations (if memory serves me right) where it would end up saving memory.

Now as I was looking at these things (and the ever helpful page on memory http://wiki.secondlife.com/wiki/LSL_Script_Memory ) I came across something that does not seem to make sense to me.

The following code comes back with 4146 used: 

list CONFIG_BUTTONS = ["Absence Off", "DayNight Off", "Set Absence", "Set Day", "Set Night", "Users"];

default
{
    touch_end(integer total_number)
    {
        string s = "a";
        llSay(0, "sb: " + (string)llGetUsedMemory());
    }
}

And then if I look at it with Psuedo-Constants it comes back with 4364, a change inline with what the wiki would suggest:

string B_USERS = "Users";
string B_ABSENCE_OFF = "Absence Off";
string B_ABSENCE_SET = "Set Absence";
string B_DAY_NIGHT_OFF = "DayNight Off";
string B_DAY_SET = "Set Day";
string B_NIGHT_SET = "Set Night";

list CONFIG_BUTTONS = [B_ABSENCE_OFF, B_DAY_NIGHT_OFF, B_ABSENCE_SET, B_DAY_SET, B_NIGHT_SET, B_USERS];

default
{
    touch_end(integer total_number)
    {
        string s = "a";
        llSay(0, "cb: " + (string)llGetUsedMemory());
    }
}

Now though I add more code to the script with no constants, and the used memory remains 4146, very strange as the use of more literals should increase the memory as far as I remember (at least it did in the LSO days):

list CONFIG_BUTTONS = ["Absence Off", "DayNight Off", "Set Absence", "Set Day", "Set Night", "Users"];

default
{
    touch_end(integer total_number)
    {
        string s = "a";  
                
        if (s == "Absence Off")
        {
            //Do something
        }
        else if (s == "DayNight Off")
        {
        }
        else if (s == "Set Absence")
        {
        }
        else if (s == "Set Day")
        {
        }
        else if (s == "Set Night")
        {
        }
        else if (s == "Users")
        {
        }
        
        llSay(0, "ss: " + (string)llGetUsedMemory());
    }
}

Puzzling away I then add similar code to the Psuedo-Constants version, and not only does it not stay the same, it rockets up to 4876, a 522 increase that I have no  idea where it comes from:

string B_USERS = "Users";
string B_ABSENCE_OFF = "Absence Off";
string B_ABSENCE_SET = "Set Absence";
string B_DAY_NIGHT_OFF = "DayNight Off";
string B_DAY_SET = "Set Day";
string B_NIGHT_SET = "Set Night";

list CONFIG_BUTTONS = [B_ABSENCE_OFF, B_DAY_NIGHT_OFF, B_ABSENCE_SET, B_DAY_SET, B_NIGHT_SET, B_USERS];

default
{

    touch_end(integer total_number)
    {
        string s = "a";

        if (s == B_ABSENCE_OFF)
        {
            //Do something
        }
        else if (s == B_DAY_NIGHT_OFF)
        {
        }
        else if (s == B_ABSENCE_SET)
        {
        }
        else if (s == B_DAY_SET)
        {
        }
        else if (s == B_NIGHT_SET)
        {
        }
        else if (s == B_USERS)
        {
        }       
                
        llSay(0, "start: " + (string)llGetUsedMemory());
    }
}

So .... Any suggestions? Anyone able to explain to me what is going on? From this small example it would appear that my use of psuedo-constants could be one of the core areas for improvement in memory, though I do not understand why.

 

Thanks in advanced from a puzzled and frustrated Wanda.

 

Share this post


Link to post
Share on other sites

LSL has no constants.

string B_USERS = "Users";
declares a variable and uses memory.

If I do that in my scripts I will not use:

list CONFIG_BUTTONS = [
because that will store this strings a 2nd time.

The compiler seems to allocate memory in blocks - sometimes. It will always use a block if you declare a user function. So I avoid to use functions for every little thing if I can avoid that.

I haven't seen a documentation of this compiler, so everything is just observations.

Share this post


Link to post
Share on other sites

Nova,

Yes I fully realize that LSL does not allow you to truly define constants, I've edited my post to hopefully make sure that comes across. I also fully understand the basics of how memory is supposed to be allocated in LSL, just that I have not looked in depth at it since MONO was released as I had not written anything that was bumping up against the memory limits until now.

The 'double' storage in this example is something I am fully aware of and in the first pair of examples, the 218 difference is to be expected, and a hit I am happy to take for readability and maintainability. What it does not explain, and what I do not see explained in the Wiki is the second pair:

  • Why in the first instance, having added code and literals does the memory not change
  • Why in the second having done the same, but simply referencing the globals does the memory usage go up 522

Share this post


Link to post
Share on other sites

Well you already encountered that memory is allocated in blocks. So a small code change can result in a big change of memory usage or no change at all.

If you just want to know how this compiler works - there is no documentation - If you find one tell me.
Without documentation there will be no info. I can imagine why it works that way, but my theory is no info since I know nothing. :)

 

Share this post


Link to post
Share on other sites

Nova .. actually not sure where you are gettng the 'memory is allocated in blocks', as far as I have read and noramlly seen that is not the case. If I take the first of the examples and simply add a global string declaration, the memory used goes up the number of bytes as indicated on the wiki for a string that size ...

Share this post


Link to post
Share on other sites

In my experience, memory allocation in Mono is simply not very predictable. At least historically, some Mono memory allocations were block-like; I seem to recall definitions of functions and states grabbing 512-byte clumps that could accrue code and variables before there were any more allocations. I'm not sure whether anything has changed, and I'm far too lazy to test it again.

However unpredictable, though, there are certainly bad practices to avoid. I, too, used to clutter my code with a lot of "constants", but have since mostly switched to "declaring" those as comments at the top, and similarly comment-flag those places in the code where the corresponding literal is used, making it easier to track down all references and change them.

Of course, if the code will only be edited within a specific dev environment, one can use preprocessor #defines and other macro text.

Share this post


Link to post
Share on other sites

Ok .. so I now see the block memory in action, though it does seem to be a bit selective when it does this. Sometimes it just adds the amount of memory as stated in the Wiki (as a noted above) and then at other points it makes the jump. I tried adding the if block, but with literals as opposed to psuedo-constants, to the base with these defined and the result was the same large jump that I saw before (4876)

string B_USERS = "Users";string B_ABSENCE_OFF = "Absence Off";string B_ABSENCE_SET = "Set Absence";string B_DAY_NIGHT_OFF = "DayNight Off";string B_DAY_SET = "Set Day";string B_NIGHT_SET = "Set Night";list CONFIG_BUTTONS = [b_ABSENCE_OFF, B_DAY_NIGHT_OFF, B_ABSENCE_SET, B_DAY_SET, B_NIGHT_SET, B_USERS];default{    touch_end(integer total_number)    {        string s = "a";                if (s == "Absence Off")        {            //Do something        }        else if (s == "DayNight Off")        {        }        else if (s == "Set Absence")        {        }        else if (s == "Set Day")        {        }        else if (s == "Set Night")        {        }        else if (s == "Users")        {        }                llSay(0, "cb: " + (string)llGetUsedMemory());    }}

So definitely down to block grabbing, and not the definition of psuedo-constants. As far as I can see the use of these is really going to be down to the number of times they are used in the code vs the size of the literal.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...