Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Constant(s)

Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
08-23-2006 13:15
lately i've chosen to define my constants through functions.

CODE
integer time(){ return 50; }


I was wondering if any one else has played around with functions as constants, if so, have you found any diverse side effects. Such as load time, script memory, extra.
Kayla Stonecutter
Scripting Oncalupen
Join date: 9 Sep 2005
Posts: 224
08-23-2006 14:18
Uh, no offence, but why not just use a variable as a constant? It'd be simpler, faster, and use less memory than a function just to get a simple number. True that you can't change the value of the function while the script is running like a variable, but I'd suggest making the 'constant var' name something noticably different than the other variables, such as all caps with underscores or something, so you're less likely to store something inside when coding. Perhaps something like this:
CODE
integer CONST_TIME = 50;
That's similar to how I use 'constants' in my scripts.
_____________________
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
08-23-2006 15:20
no offense is taken, in-fact I posted this to get feed back. I was curious to how a functions as constants, would compare to a variable being used as a constant. Mostly towards memory saving. Can I ask how you figured out a function would take more memory? Would it matter if your storing a large list?
Tek Harbinger
SS Maggot Elite
Join date: 19 Oct 2005
Posts: 49
08-23-2006 15:33
i'm just wondering why you would make something that is constant as a function. when calling data from a variable, that's all it has to do, the data is there. but when calling a function, it has to execute the function code, and then return the result, practically doubling the execution load. look at the difference between defining a constant and calling a function to get the same result.

1) get data
2) call function -> execute function -> return result

not sure if it would actually take more memory, but defining a constant as a function would probably slow the process down. it is a small loss, but can add up in the end.
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
08-23-2006 15:46
It would take more memory in a couple of ways. One, the code for the function has to be stored, and you can bet that the code for a simple function that takes no parameters and returns an integer, is bigger than the memory taken up by the integer itself. Then, when you call the function, your script's call stack has to have an entry added to it. That takes up memory too, and the script wouldn't have to do that if it were accessing a variable directly.

Also, having to execute more instructions means it'll take longer to run as well. I'm really not sure there's any advantage to doing it this way.
bucky Barkley
Registered User
Join date: 15 May 2006
Posts: 200
08-23-2006 16:59
The other thing to bear in mind here is that it is good practice to group constants together. This is usually done at the top of the file. The provides a "one stop shopping" place to tweak things. Scattering them amongst functions makes it harder to find all of the definitions.
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
08-23-2006 19:04
I just did an experiment, I wrote 3 simple scripts. One was a default script. Just reporting memory. I then wrote a script storing a key as a list value, and then another as a function returning the value of a list. In order this was the result: 16172, 16103, 16106. Based a pone the results it dose appear variables take more memory in this case 3 bytes.

Bellow are the scripts I used in my testing.

CODE
//script A
default
{
state_entry()
{
llOwnerSay ( (string)llGetFreeMemory() );
}
}
//returns value of "16172"


CODE
//script B
list constant = ["dad360b9-6617-4cbe-a7d3-9367a6cfaed1"];

default
{
state_entry()
{
llOwnerSay ( (string)llGetFreeMemory() );
}
}
//returns value of "16103"


CODE
//script C
list constant(){ return ["dad360b9-6617-4cbe-a7d3-9367a6cfaed1"];}

default
{
state_entry()
{
llOwnerSay ( (string)llGetFreeMemory() );
}
}
//returns value of "16106"


using the scripts above I tried running the scripts with different numbers of keys. Note all keys in the list, were the same key/string. I repeated each variation of the test several times to make sure the results is constant. Note: I did not vary the key.
Formating of results: number of keys in list. Results of script B, Results of script C.
1 keys: 16103, 16106
2 keys: 16066, 16055
3 keys: 16007, 16026
4 keys: 15959, 15986
5 keys: 15911, 15946
6 keys: 15863, 15906
7 keys: 15815, 15866

difference: (2nd number subtracted from the first number)
Formating of results: number of keys in script, ( results of script B - script C ), -1( results of results of script B - script C / number of keys in script )
1 key(s): -3 3
2 key(s): 11 -5.5
3 key(s): -19 6.333
4 key(s): -27 6.75
5 key(s): -35 7
6 key(s): -43 7.1666667
7 key(s): -51 7.2857143

further testing is on the way. But based a pone preliminary results, it dose appear to be an advantage to storing constant lists as list returning functions. It also appears to be a greater amount of savings the more items there are in the list.
But I am curious as to why 2 keys in a list returns results different from the pattern.
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
08-23-2006 20:01
Using the scripts above with 1 keys in list:
number of calls, calls as variable, calls as functions
0 calls: 16103, 16106, -3, -3
1 calls: 16097, 16024, 73, 73
2 calls: 16091, 16001, 90, 45
3 calls: 16085, 15978, 107, 35.66666666667
4 calls: 16079, 15955, 124, 31
5 calls: 16073, 15932, 141, 28.2
6 calls: 16067, 15909, 158, 26.33333333333
7 calls: 16061, 15886, 175, 25

looking at the results above
variable call: up to 6 bites per call
function call: up to 82 bites per call

comparing the results, it seems 6 bites per variable call is accurate.
BUT for function calls, the results changes the more often it is called.
Looking at the patterns above, the bites per call decreases as it's called more often.
1 : 82
2 : 52.5
3 : 42.6667
4 : 37.75
5 : 34.8
6 : 32

base on the noticed trend I ran the with more function calls
40 : 24.475
80 : 23.7375
160 : 23.36875

But it appears 23 is about as small as a function call can get.

Taking into account the gain per item in a list as a function, and the draw back of each function call. When calling a large constant list of keys ones, functions are better. When calling small list of keys frequently variables are better.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-24-2006 13:04
I suspect garbage collection may be having interesting effects on your analyses, but I could be wrong.
Kayla Stonecutter
Scripting Oncalupen
Join date: 9 Sep 2005
Posts: 224
08-25-2006 01:27
Did some simple speed tests, with the following two scripts:
CODE
integer     x;
integer test;

integer VarCheck = 1000;

default
{
touch_start(integer total_number)
{
llOwnerSay("starting VarCheck");
llResetTime();
for(x = 0; x < 1000; ++x)
{
test = VarCheck;
}
llOwnerSay((string)llGetTime());
}
}

CODE
integer     x;
integer test;

integer FuncCheck()
{
return 1000;
}

default
{
touch_start(integer total_number)
{
llOwnerSay("starting FuncCheck");
llResetTime();
for(x = 0; x < 1000; ++x)
{
test = FuncCheck();
}
llOwnerSay((string)llGetTime());
}
}

Ran each test dozens of times. With the first test I was consistantly getting around 0.8 - 0.9 seconds. With the second script, I was consistantly getting 1.6 - 1.7 seconds.

Is there anyone reading this thread that really understands LSL (Strife maybe? :P) that can tell us exactly what the memory difference is between variables and functions, without having to use the simple and not fully reliable llGetFreeMemory()?
_____________________