Difference between revisions of "LSL Script Memory"

From Second Life Wiki
Jump to navigation Jump to search
(Add findings about interned strings)
 
(7 intermediate revisions by 5 users not shown)
Line 4: Line 4:
All scripts in LSL  pre-MONO start out with 16 kilobytes of memory. Mono scripts start with 64 kilobytes, this may be reduced with [[llSetMemoryLimit]](). Additionally, Mono scripts only use the amount of real memory that they currently need, not the amount allocated to them (64kB, or whatever was set by [[llSetMemoryLimit]](). Mono scripts also share the memory needed for their bytecode with all other instances in the same region of the same script copied after compilation. Below is a list of code and the memory usage.
All scripts in LSL  pre-MONO start out with 16 kilobytes of memory. Mono scripts start with 64 kilobytes, this may be reduced with [[llSetMemoryLimit]](). Additionally, Mono scripts only use the amount of real memory that they currently need, not the amount allocated to them (64kB, or whatever was set by [[llSetMemoryLimit]](). Mono scripts also share the memory needed for their bytecode with all other instances in the same region of the same script copied after compilation. Below is a list of code and the memory usage.


All of the following data was collected through [[llGetFreeMemory]](). As the LSL compiler is not a simple program, the data below may not be 100% accurate, in fact, much of it is wrong and could use corrections.
Much of the following data was collected through [[llGetFreeMemory]](). The revised figures for Mono lists were obtained via [[llGetUsedMemory]](). As the LSL compiler is not a simple program, the data below may not be 100% accurate, in fact, much of it is wrong and could use corrections.


There are still many bits that could be improved upon, and many more that could use more detail. If anyone has any free time, play around with the memory usage for different functions. A list of needed updates is at the end of the page.
There are still many bits that could be improved upon, and many more that could use more detail. If anyone has any free time, play around with the memory usage for different functions. A list of needed updates is at the end of the page.
Line 11: Line 11:
See the end of this page.
See the end of this page.
==Declaring variables as global==
==Declaring variables as global==
===Variable Memory Usage===
===Variable Memory Usage (Pre Mono) ===
<pre>
<pre>
integer  10
integer  10
Line 21: Line 21:
list    21 + list memory usage
list    21 + list memory usage
</pre>
</pre>
===List Memory Usage===
=== List Memory Usage (MONO) (Revised findings as of Jan 2013) ===
<pre>
integer  16
float    16
string  18 + 2 per character
interned string  4 (must be inserted as a reference to a pre-existing string)
key      102
key as string  90
vector  24
rotation 28
list    Lists Can Not Contain Lists
</pre>
For other results relating to Mono see https://wiki.secondlife.com/wiki/User:Omei_Qunhua
===List Memory Usage (Pre MONO) ===
<pre>
<pre>
integer  15
integer  15
Line 31: Line 44:
list    Lists Can Not Contain Lists
list    Lists Can Not Contain Lists
</pre>
</pre>
=== List Memory Usage (MONO) ===
 
<pre>
integer  20
float    20
string  22 + 2 per character
key      34 + 2 per character
vector  28
rotation 32
list    Lists Can Not Contain Lists
</pre>


String entries have a constant 8 for pre-compile text.  
String entries have a constant 8 for pre-compile text.  
Line 105: Line 109:
6 bytes to reference variables
6 bytes to reference variables
==Examples==
==Examples==
<lsl>
<source lang="lsl2">
integer i; //10 bytes
integer i; //10 bytes


Line 113: Line 117:
  }
  }
}
}
</lsl>
</source>


=Functions=
=Functions=
Line 119: Line 123:
Functions require 16 bytes to be created, with 3 bytes per parameter, plus bytes commensurate with the return type.
Functions require 16 bytes to be created, with 3 bytes per parameter, plus bytes commensurate with the return type.


In Mono, however, functions and event handlers take up memory in '''512-byte chunks'''Even an empty function requires at leasst 512 bytes.  (Empty event handlers, however, apparently do not.)  The code within the function takes up whatever bytes are not required by the declarationOnce the code + declaration fills a 512-byte chunk, another whole chunk is allocated to it.
Tests in January 2013 show that user functions in Mono no longer (if ever) automatically take up a block of memory (512 bytes) eachAs with all Mono code, an extra 512-block of memory is used when needed, but not automatically per user function. In addition the perceived memory usage can vary depending, it is thought, on the action of periodic garbage collectionInserting an llSleep() for instance, maybe allowing garbage collection to jump in, before reading memory usage, can show a reduction in space used.


===Return Types===
===Return Types===
Line 169: Line 173:


==Examples==
==Examples==
<lsl>
<source lang="lsl2">
list f() {  //16 (function) + 4 (return)
list f() {  //16 (function) + 4 (return)
     list ret = [0]; //11 (list) + 7 (integer)
     list ret = [0]; //11 (list) + 7 (integer)
     return ret; 6 (list)
     return ret; 6 (list)
}   
}   
</lsl>
</source>
<lsl>
<source lang="lsl2">
string f() {
string f() {
     return "";
     return "";
Line 185: Line 189:
     }
     }
}
}
</lsl>
</source>


=Operators=
=Operators=
Line 212: Line 216:
Assigning values to variables takes as many bytes as used minus one.
Assigning values to variables takes as many bytes as used minus one.
===Examples===
===Examples===
<lsl>
<source lang="lsl2">
string s; //12 bytes
string s; //12 bytes
s;        //6 bytes
s;        //6 bytes
"";      //3 bytes (see below)
"";      //3 bytes (see below)
s = "";  //8 (6 (string) + 3 (null string) - 1) bytes
s = "";  //8 (6 (string) + 3 (null string) - 1) bytes
</lsl>
</source>
However...
However...
<lsl>
<source lang="lsl2">
string s = ""; //12 bytes
string s = ""; //12 bytes
</lsl>
</source>
<lsl>
<source lang="lsl2">
integer i; //15 bytes
integer i; //15 bytes
i = i + 1 // 6 bytes (integer) + 6 bytes (integer) + 6 bytes (1) + 1 byte (addition) - 1 byte (assignment)
i = i + 1 // 6 bytes (integer) + 6 bytes (integer) + 6 bytes (1) + 1 byte (addition) - 1 byte (assignment)
</lsl>
</source>


==Statements==
==Statements==
Line 238: Line 242:
</pre>
</pre>
===Examples===
===Examples===
<lsl>
<source lang="lsl2">
if (5 < 10) { // 6 (if) + 6 (integer) + 6 (integer) + 1 (compare)
if (5 < 10) { // 6 (if) + 6 (integer) + 6 (integer) + 1 (compare)
//Do something here
//Do something here
}
}
</lsl>
</source>
<lsl>
<source lang="lsl2">
while (1 < 2 & 3 < 4) { // 11 (while) + 4*6 (4 integers) + 2 (2 compares)
while (1 < 2 & 3 < 4) { // 11 (while) + 4*6 (4 integers) + 2 (2 compares)
//Do something here
//Do something here
}
}
</lsl>
</source>


==Typecasting==
==Typecasting==
Line 270: Line 274:
** How return types effect the return
** How return types effect the return
* In the following code, the call to llGetFreeMemory() returns a different value. How is it affected? Why?
* In the following code, the call to llGetFreeMemory() returns a different value. How is it affected? Why?
<lsl>
<source lang="lsl2">
default {
default {
     state_entry() {
     state_entry() {
Line 278: Line 282:
     }
     }
}
}
</lsl>
</source>
 
[[Category:LSL Memory]]
=Update pending=
<lsl>
////////////////////////////////////////////////////////////////////////////////
// 
//  Script memory - work in progress
// 
//  (c) 1012
//  llDeleteSubString( "yepey Resident", llSubstringIndex( "yepey Resident", " " ),  -1 );
// 
//  The script won't compile due to previously decalerd variables.
//  This script will, when finished, replace all of the above.
// 
//  Regards,
//  yepey
// 
// 
//          GLOBAL VARIABLES
//          --------------------------------------------------------------------
integer    int = 0;                                        // 8
float      fl  = 0.0;                                      // 8
string      str = "";                                      // 22
string      str = "a";                                      // 22 + 2
string      str = "\n";                                    // 22 + 2
key        id  = "";                                      // 8
key        id = NULL_KEY;                                  // 8
key        id = "a822ff2b-ff02-461d-b45d-dcd10a2de0c2";    // 8
vector      v  = ZERO_VECTOR;                              // 16
vector      v  = < 0, 0, 0 >;                              // 16
rotation    r  = ZERO_ROTATION;                            // 16
rotation    r  = < 0, 0, 0, 1 >;                          // 16
list        l  = [];                                      // 44
list        l  = [                                         // 44 + o.O
                    0,                                      //    28
                    1.0,                                    //    28
                    "",                                    //    30
                    "a",                                    //    32
                    "\n",                                  //    32
                    NULL_KEY,                              //  102
                    ZERO_VECTOR,                            //    36
                    ZERO_ROTATION                          //    40
                  ];
 
default
{
   
    state_entry()
    {
       
//      LOCAL VARIABLES
//      ------------------------------------------------------------------------
        integer    int = 0;                                        // 4
        float      fl  = 0.0;                                      // 4
        string      str = "";                                      // 18 +
        string      str = "a";                                      //    2
        string      str = "\n";                                    //    2
        key        id  = "";                                      // 4
        key        id = NULL_KEY;                                  // 4
        key        id = "a822ff2b-ff02-461d-b45d-dcd10a2de0c2";    // 4
        vector      v  = ZERO_VECTOR;                              // 12
        vector      v  = < 0, 0, 0 >;                              // 12
        rotation    r  = ZERO_ROTATION;                            // 16
        rotation    r  = < 0, 0, 0, 1 >;                          // 16
        list        l  = [];                                      // 40
        list        l  = [                                        // 40 + o.O
                            0,                                      //    16
                            1.0,                                    //    16
                            "",                                    //    18 +
                            "a",                                    //      2
                            "\n",                                  //      2
                            NULL_KEY,                              // 90
                            ZERO_VECTOR,                            // 24
                            ZERO_ROTATION                          // 28
                            ];
       
    }
   
}
 
state examples
{
   
    state_entry()
    {
       
        /* IMPLEMENTATION NEEDED  */
       
    }
   
}
</lsl>

Latest revision as of 09:26, 5 April 2017

Script Memory

All scripts in LSL pre-MONO start out with 16 kilobytes of memory. Mono scripts start with 64 kilobytes, this may be reduced with llSetMemoryLimit(). Additionally, Mono scripts only use the amount of real memory that they currently need, not the amount allocated to them (64kB, or whatever was set by llSetMemoryLimit(). Mono scripts also share the memory needed for their bytecode with all other instances in the same region of the same script copied after compilation. Below is a list of code and the memory usage.

Much of the following data was collected through llGetFreeMemory(). The revised figures for Mono lists were obtained via llGetUsedMemory(). As the LSL compiler is not a simple program, the data below may not be 100% accurate, in fact, much of it is wrong and could use corrections.

There are still many bits that could be improved upon, and many more that could use more detail. If anyone has any free time, play around with the memory usage for different functions. A list of needed updates is at the end of the page.

Variables

See the end of this page.

Declaring variables as global

Variable Memory Usage (Pre Mono)

integer  10
float    10
string   18 + 1 per character
key      18 + 1 per character
vector   18
rotation 22
list     21 + list memory usage

List Memory Usage (MONO) (Revised findings as of Jan 2013)

integer  16
float    16
string   18 + 2 per character
interned string  4 (must be inserted as a reference to a pre-existing string)
key      102 
key as string  90
vector   24
rotation 28
list     Lists Can Not Contain Lists

For other results relating to Mono see https://wiki.secondlife.com/wiki/User:Omei_Qunhua

List Memory Usage (Pre MONO)

integer  15
float    15
string   12 + 1 per character
key      12 + 1 per character
vector   23
rotation 27
list     Lists Can Not Contain Lists


String entries have a constant 8 for pre-compile text.

myList = ["testing", "1", "asdhdgkjajlgsdfdsw"]
   (8, 8, 8)
myList = [llGetSubString("testing", 0, -1), (string)1, llToUpper("asdhdgkjajlgsdfdsw")]
   (22 + 14, 22 + 2, 22 + 36)

Declaring variables inside default state

Variable Memory Usage

integer  15
float    15
string   12 + 1 per character
key      12 + 1 per character
vector   31
rotation 39
list     15 + list memory usage

List Memory Usage

integer  7
float    7
string   4 + 1 per character
key      4 + 1 per character
vector   23
rotation 30
list     Lists Can Not Contain Lists

Simply stating values

Putting a Value onto the Stack

Integers 1 + 4 bytes for the value
Float    1 + 4 bytes for the value
String   1 + bytes for characters + 1 byte for null
Key      1 + bytes for characters + 1 byte for null
Vector   1 + 3 * float cost
Rotation 1 + 4 * float cost
List     1 + 4 for list length + list memory usage

To remove a value from the stack costs 1 byte.

List Memory Usage

Integers 7
Float    7
String   4 + 1 per character
Key      4 + 1 per character
Vector   23
Rotation 30
list     Lists Can Not Contain Lists

Constants

All integer constants use 6 bytes of memory.

Other Constants

ZERO_VECTOR   16
ZERO_ROTATION 21
NULL_KEY      39

Extras

6 bytes to reference variables

Examples

integer i; //10 bytes

default {
 state_entry() {
  list l = ["Testing", "This"] //15 (list) + 15 (string) + 8 (string)
 }
}

Functions

Declaring functions

Functions require 16 bytes to be created, with 3 bytes per parameter, plus bytes commensurate with the return type.

Tests in January 2013 show that user functions in Mono no longer (if ever) automatically take up a block of memory (512 bytes) each. As with all Mono code, an extra 512-block of memory is used when needed, but not automatically per user function. In addition the perceived memory usage can vary depending, it is thought, on the action of periodic garbage collection. Inserting an llSleep() for instance, maybe allowing garbage collection to jump in, before reading memory usage, can show a reduction in space used.

Return Types

integer  4
float    4
string   4
key      4
vector   20
rotation 27
list     4

Declaring variables in functions

Variable Memory Usage

integer  11
float    11
string   8 + 1 per character
key      8 + 1 per character
vector   19
rotation 23
list     11 + list memory usage

List Memory Usage

integer  7
float    7
string   4 + 1 per character
key      4 + 1 per character
vector   23
rotation 30
list     Lists Can Not Contain Lists

Calling functions

21 bytes to call a function with no return
21 bytes to call a function with any return + type of return
Subtract number of parameters entered

Return Types

integer  2
float    2
string   10 + 1 per character returned
key      10 + 1 per character returned
vector   2
rotation 2
list     18 + list memory usage

Examples

list f() {  //16 (function) + 4 (return)
    list ret = [0]; //11 (list) + 7 (integer)
    return ret; 6 (list)
}
string f() {
    return "";
}

default {
    state_entry() {
        f();   //21 (call to f) + 10 (returns string)
    }
}

Operators

List of Operators

+  1
-  1
*  1
/  1
%  1
&  0
|  0
^  0
!  0
>> 0
<< 0
~  1
== 1
<= 1
<  1
>= 1
>  1
!= 1

Assignment

Assigning values to variables takes as many bytes as used minus one.

Examples

string s; //12 bytes
s;        //6 bytes
"";       //3 bytes (see below)
s = "";   //8 (6 (string) + 3 (null string) - 1) bytes

However...

string s = ""; //12 bytes
integer i; //15 bytes
i = i + 1 // 6 bytes (integer) + 6 bytes (integer) + 6 bytes (1) + 1 byte (addition) - 1 byte (assignment)

Statements

if    6
while 11
for   11
do    6
jump  5
@     0
state 5

Examples

if (5 < 10) { // 6 (if) + 6 (integer) + 6 (integer) + 1 (compare)
//Do something here
}
while (1 < 2 & 3 < 4) { // 11 (while) + 4*6 (4 integers) + 2 (2 compares)
//Do something here
}

Typecasting

integer  10
float    10
string   10
key      10
vector   10
rotation 10
list     25

States

14 bytes for any event in a state + 1 for each parameter 17 bytes to create a new state

Needed Updates

Several updates are needed for this page, the most needed are listed below:

  • Verification of all data
  • Clarification of explanations
  • Investigations into how the functions work
    • Calling of functions
    • How return types effect the return
  • In the following code, the call to llGetFreeMemory() returns a different value. How is it affected? Why?
default {
     state_entry() {
          llOwnerSay((string)llGetFreeMemory());
          list l = ["", "", "", ""];
          llOwnerSay((string)llGetFreeMemory());
     }
}