Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

LSL2 vs Mono benchmarks/tests.

shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-02-2008 15:38
Just thought I would dump a bunch of my tests I've been doing into this thread. Feel free to ad your own tests you have done.

Testing Aaron Linden's Visitor Counter freebie script that is everywhere. I made two versions, added in a few lines for the script to say its memory usage, and compiled one mono, one LSL2.

After logging 99 Users, memory usage is:
[14:26] Visitor Counter (v2+NONmono): Memory Free: 8624 of 14411 (59.898685%)
[14:26] Visitor Counter (v2+mono): Memory Free: 51566 of 56420 (91.396670%)

LSL2: 5787 bytes used to store 99 names.
Mono: 4854 bytes used to store 99 names.
shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-02-2008 15:43
Wrote a quick script to add data to a list over and over.

Difference in amount of storage space is staggering.

LSL2: 15483 Bytes of space gets filled with 68 List entries, each 100 Characters long. (6,800 Characters)

Mono: 59287 Bytes of space gets filled with 7388 List entries, each 100 Characters long. (738,800 Characters)


Mono stores 108.64 Times more data with this script.

LSL2 Has a Byte Cost per Character of 2.236
Mono Has a Byte Cost per Character of 0.802

Code:
CODE

// (c) Shiney Sprocket 2008 - Simple script to fill a list.
integer startmem;
integer starttime;
integer usage;
float percent;
string data="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
list memoryusageholethatwillbefilled;

useMemory() {
memoryusageholethatwillbefilled+=[data,data,data,data];
usage=llGetFreeMemory();
percent=((float)usage/(float)startmem)*100;
integer length=llGetListLength(memoryusageholethatwillbefilled);
string bps=(string)(((float)startmem-(float)usage)/(llGetUnixTime()-starttime));
float cost=((float)(startmem-usage)/(float)(length*100));
llSetText("Memory Free: "+(string)usage+" of "+(string)startmem+" ("+(string)percent+"%) (bps: "+bps+") (List: "+(string)length+") (CostPerCharacter: "+(string)cost+")",<1,1,1>,1);

}

default
{
state_entry()
{
starttime=llGetUnixTime();
startmem=llGetFreeMemory();
llSleep(1);
@top;
useMemory();
jump top;
}

touch_start(integer detected) {llResetScript();}
}


-edit-
Should point out,
memoryusageholethatwillbefilled+=[data,data,data,data];

makes little difference if it is just
memoryusageholethatwillbefilled+=[data];

Just takes longer to fill. (LSL2 seems to only fit 62 entries when I tried it with just one data being added to list)
shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-02-2008 15:52
Same idea as above, but using a STRING.

LSL2: 15512 Bytes of space gets filled with a string 5400 Characters long (0.284 byte cost per character).
Mono: 59364 Bytes of space gets filled with a string 29600 Characters long (0.0200 byte cost per character)

Lists store ~25x more data then a single string would.


CODE

// (c) Shiney Sprocket 2008 - Simple script to fill a string.
integer startmem;
integer starttime;
integer usage;
float percent;
string data="1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
string memoryusageholethatwillbefilled;

useMemory() {
memoryusageholethatwillbefilled+=data;
usage=llGetFreeMemory();
percent=((float)usage/(float)startmem)*100;
integer length=llStringLength(memoryusageholethatwillbefilled);
string bps=(string)(((float)startmem-(float)usage)/(llGetUnixTime()-starttime));
float cost=((float)(startmem-usage)/(float)(length*100));
llSetText("Memory Free: "+(string)usage+" of "+(string)startmem+" ("+(string)percent+"%) (bps: "+bps+") (Length: "+(string)length+") (CostPerCharacter: "+(string)cost+")",<1,1,1>,1);

}

default
{
state_entry()
{
starttime=llGetUnixTime();
startmem=llGetFreeMemory();
llSleep(1);
@top;
useMemory();
jump top;
}

touch_start(integer detected) {llResetScript();}


}
Very Keynes
LSL is a Virus
Join date: 6 May 2006
Posts: 484
09-02-2008 16:20
Interesting results shiney thanks for sharing,

I have noticed similar results with list storage but have not had a chance to quantify them as I have been out of town most if the past week.
Just as a matter of interest had any one compared lists using Strife's famous

list = (list = []) + list + [New-data]

vs.

list += [new-data]

Most of, in fact all of, my scripts use the former (Strife is my hero) but I wondered if I need to strip that out now.
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
09-02-2008 17:08
From: shiney Sprocket
Same idea as above, but using a STRING.

LSL2: 15512 Bytes of space gets filled with a string 5400 Characters long (0.284 byte cost per character).
Mono: 59364 Bytes of space gets filled with a string 29600 Characters long (0.0200 byte cost per character)

You're mistaking something about what llGetFreeMemory is telling you, at a glance. I don't feel like looking at the actual code (my god, man, spaces, use them). It's silly to assume that a string will only fit 5400 characters and use 15512 bytes. The reason it reports as such is because llGetFreeMemory is a low-water mark..

Similarly, it's ridiculous to assume you can consistently store 700,000 characters in a single script in any fashion. The only reason you were able to is due to some wacky way Mono handles duplicate list elements.
_____________________
shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-02-2008 18:59
Those were the results at the point the script crashed due to it hitting the max memory usage. It is not relying on max free memory for anything other then that was the last thing llSetText set before it crashed. I realize there are other factors to llGetFreeMemory.

I'm referring to results with this script, not over every script in second life.

However, your duplicate list issue may be correct. I will test it right away.
shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-02-2008 19:14
OK, redid the list test with random data on Mono&LSL2. The data being the same skewed the previous tests.

List was able to fit (various runs on MONO):
112 entries with a total size of 26,622 Characters.
112 entries with a total size of 26,617 Characters.
113 entries with a total size of 26,856 Characters.
...

List was able to fit (various runs on MONO):
25 entries with a total size of 5,945 Characters.
26 entries with a total size of 6,180 Characters.
26 entries with a total size of 6,177 Characters.
...

And bahh to spaces, this is test code, not development code. I just thought I would share my messing around for comments. Thanks to yours for pointing out a flaw.

Also, due to the way I quickly used frand, the data size shifts so it is counted with a new variable.

Should note these results seem pretty expected due to increased memory available. Mono stores just over 4x more data, as should be expected by the ~4x larger memory availability.


CODE

integer startmem;
integer starttime;
integer usage;
float percent;
string data;
integer length2=0;
list memoryusageholethatwillbefilled;

useMemory() {
data=(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999)+(string)llFrand(99999);
length2+=llStringLength(data);
memoryusageholethatwillbefilled+=[data];
usage=llGetFreeMemory();
percent=((float)usage/(float)startmem)*100;
integer length=llGetListLength(memoryusageholethatwillbefilled);
string bps=(string)(((float)startmem-(float)usage)/(llGetUnixTime()-starttime));
float cost=((float)(startmem-usage)/(float)(length*100));
llSetText("Memory Free: "+(string)usage+" of "+(string)startmem+" ("+(string)percent+"%) (bps: "+bps+") (List: "+(string)length+") (String Size: "+(string)length2+") (CostPerCharacter: "+(string)cost+")",<1,1,1>,1);

}

default
{
state_entry()
{
starttime=llGetUnixTime();
startmem=llGetFreeMemory();
llSleep(1);
@top;
useMemory();
jump top;
}

touch_start(integer detected) {llResetScript();}


}
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
09-03-2008 00:13
The point is.. the maximum memory used is not how many characters you're storing. When you concatenate the string, you make a copy in memory which can double (or more) your current memory usage and you'll stack-heap before it'll ever let you know how many characters you were actually able to tack on. This was one of the applications of the memory hack Strife made (which I'm not sure still works).

Especially the way you're doing it, which generates a LARGE number of new elements..
_____________________
shiney Sprocket
Registered User
Join date: 24 Jan 2006
Posts: 254
09-03-2008 14:07
From: Tyken Hightower
The point is.. the maximum memory used is not how many characters you're storing. When you concatenate the string, you make a copy in memory which can double (or more) your current memory usage and you'll stack-heap before it'll ever let you know how many characters you were actually able to tack on. This was one of the applications of the memory hack Strife made (which I'm not sure still works).

Especially the way you're doing it, which generates a LARGE number of new elements..


I know that. I was just testing to see what results Mono would give with this sort of script and how many characters it would store before crashing. Does this not accomplish that? It gives me a rough idea how big I can have a list.

I was really looking to see how much conversation could fit in a List VS Array.