differance efficency (constants versus hard typing)
|
|
Scott Tureaud
market base?
Join date: 7 Jun 2007
Posts: 224
|
04-24-2008 15:34
while it's a nice programming practice to use constants is it worth it when you look at efficeny of a script you're never going to touch again. since lsl is bytecode(for now) what would the differance be between having a dozen to a few dozen constants(that are completely normal variables as for as the bytecode reads/compiles). versus having the byte code having the numbers as just hard typed. llwhatever(5, 6, "asdfa"  = hard typing llwhatever(var, differentvar, strvar) = constants to sum it up the difference in efficiency between those two statements up above.
|
|
Darien Caldwell
Registered User
Join date: 12 Oct 2006
Posts: 3,127
|
04-24-2008 16:18
For Strings, i have found using a variable as a constant that is used repeatedly will save script memory.
For Integers, i see no difference between using a variable, or 'hard typing'.
For other data types, I don't know.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
04-24-2008 18:22
Discussions like this have historically ended up as our biggest fights in the Scripting Forum It may take a small (very, very, very small) amount of extra time when it compiles into bytecode, but other then that it is strictly personal choice. Write the code so you personally can read it, that's all that matters. There are umpteen jillion "rules" for coding and I don't pay attention to any of em. In most cases, we aren't working on shared projects that others have to contribute to. Some people write beautiful code with declared variables like this "gIntcount", showing that "count" is a global integer. Me I just declare "count" and know what it means. If after 6 months, you can go back and still read a script you wrote, then you wrote it perfectly!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
04-24-2008 18:54
From: Jesse Barnett Discussions like this have historically ended up as our biggest fights in the Scripting Forum They have also been one the greatest sources of examples for both efficiency and style.  From: someone It may take a small (very, very, very small) amount of extra time when it compiles into bytecode, but other then that it is strictly personal choice. That really depends on the scripts and application. To conserve memory, I have "folded" numerous copies of the same key/string/list into a variable and been able to wring up to several kilobytes of space from the effort. Did you know that doing this: key gkNullKey = NULL_KEY; and using gkNullKey everywhere in your script where you normally use NULL_KEY can potentially save you a kilobyte in memory in a fairly complex data handling script? From: someone Write the code so you personally can read it, that's all that matters. There are umpteen jillion "rules" for coding and I don't pay attention to any of em. In most cases, we aren't working on shared projects that others have to contribute to. Some people write beautiful code with declared variables like this "gIntcount", showing that "count" is a global integer. Me I just declare "count" and know what it means. If after 6 months, you can go back and still read a script you wrote, then you wrote it perfectly! Yup, style is all a matter of taste, until you share it with someone else. Is why I try to make the stuff I post to the public as pretty and readable as I can make it. I want to lessen the "reading it" curve for everyone else as much as possible. It's OK if people don't. I tend to take a lot of code posted in the library, clean it up, make it more efficient/flexible, fix bugs/exploits/weaknesses, and then use the result. Except in the rare case where memory is critical, I avoid shortcuts, even though they may be valid compilable statements. But, like you say, it is personal preference. Programming has always been that way. There May Be More Than One Way To Do It, but my corollary is: There Are Fewer Best Ways To Do It. 
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
04-24-2008 19:47
From: Talarus Luan They have also been one the greatest sources of examples for both efficiency and style.  Couldn't agree more. When I was learning, I loved those discussions (sometimes heated), which at the time were over my head. Still remember when everyone started using capital letters whenever Strife popped in with one of his examples  Some still ask me why I post code examples instead of just pointing to the wiki. I seriously miss the days where everyone would post thier own way of doing complete scripts, everyone trying to make it a little more effcient or faster. It is one thing seeing a single command in the wiki and another to see beautiful, flowing examples of scripts and how the different functions interact and most importantly all of the different styles. I can recognise a lot of scripts without seeing the creator's name just by looking at the style.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
05-22-2008 03:16
Just the thread I was looking for! <grins>
Talarus - I wnat to understand your comment about the NULL_KEY ... I assume that the savings come because each time you use the LSL Constant NULL_KEY in your code, 39 bytes are take, where as a global Key variable takes 18 bytes + 1 byte per char. Cant remeber how many chars are in a key but even at a top of 50 we are already saving memory on two uses of NULL_KEY.
So I understand this correctly?
If that is the case then a question. Out of habit I do use 'constants' over values as a rule in my code, makes it more readable etc. But I am seeing that unless I use the constant a number of times it may be less memory efficient. From the Wiki on Memory:
Global String bytes = 18 + 1/char Stated String bytes = 1 + 1/char + 1 null
So the following would use 18 + 19 = 37 bytes
//Global string DATA_NOTECARD = "control_data_params";
Whereas if I were to simply use the string in code it would take 21 bytes. And if I only used the constant once having the global has cost me 16 bytes. On the positive side, once I use the constant more than once I start sving.
Correct?
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
05-22-2008 03:49
Following on with another memory question .. was looking at the difference between a global variable and a state level variable, particularly a List. If I were to have a List, containing 5 strings or 10 chars each the memory cost would be:
Global = 21 + 5 * (12 + 10) or 131 State = 15 + 5 * (4 + 10) or 85
So what I see from this is that unless you are using multiple states that need to access the List or have global level functions that access the list declaring at a state level is much more efficient. In fact if you never use other than the defualt state, declaring your functions and 'global' variables at the state level will save memory. Though the data on the Wiki for memory shows some strange anolomies where Globals are more efficient than State or Function Level variables:
Global Int/Float 10 - State Int/Float 15 - Function Int/Float 11 Global Vector 18 - State Vector 31 - Function Vector 19 Global Rot 22 - State Rot 39 - Function Rot 23
Is there a reason that anyone knows why the Global here is so much more efficient? Or particularly why the state is so inefficient?
This is particularly strange when one looks at the memory that these items require in a list at the different levels. There the State and Functions are more efficient (with the exception of a Rot that costs 3 bytes more).
|
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
05-22-2008 12:52
From: Shifting Dreamscape Talarus - I wnat to understand your comment about the NULL_KEY ... I assume that the savings come because each time you use the LSL Constant NULL_KEY in your code, 39 bytes are take, where as a global Key variable takes 18 bytes + 1 byte per char. Cant remeber how many chars are in a key but even at a top of 50 we are already saving memory on two uses of NULL_KEY.
So I understand this correctly? Yes, that is correct. The LSL compiler does not do ANY optimizations at all, including "constant folding", which is where only one copy of every constant used is stored, and simply referenced everywhere else. From: someone If that is the case then a question. Out of habit I do use 'constants' over values as a rule in my code, makes it more readable etc. But I am seeing that unless I use the constant a number of times it may be less memory efficient. From the Wiki on Memory:
Global String bytes = 18 + 1/char Stated String bytes = 1 + 1/char + 1 null
So the following would use 18 + 19 = 37 bytes
//Global string DATA_NOTECARD = "control_data_params";
Whereas if I were to simply use the string in code it would take 21 bytes. And if I only used the constant once having the global has cost me 16 bytes. On the positive side, once I use the constant more than once I start sving.
Correct? That's correct. One use of a "large constant" is best left in your code as a constant (note that, for integers and floats, it doesn't matter anyway). Any more than that, depending on the size of the constant value, you may start seeing a savings with as little as one additional use, if you put it in a variable. You're doing the math right.  From: someone Following on with another memory question .. was looking at the difference between a global variable and a state level variable, particularly a List. If I were to have a List, containing 5 strings or 10 chars each the memory cost would be:
Global = 21 + 5 * (12 + 10) or 131 State = 15 + 5 * (4 + 10) or 85
So what I see from this is that unless you are using multiple states that need to access the List or have global level functions that access the list declaring at a state level is much more efficient. In fact if you never use other than the defualt state, declaring your functions and 'global' variables at the state level will save memory. Though the data on the Wiki for memory shows some strange anolomies where Globals are more efficient than State or Function Level variables:
Global Int/Float 10 - State Int/Float 15 - Function Int/Float 11 Global Vector 18 - State Vector 31 - Function Vector 19 Global Rot 22 - State Rot 39 - Function Rot 23
Is there a reason that anyone knows why the Global here is so much more efficient? Or particularly why the state is so inefficient?
This is particularly strange when one looks at the memory that these items require in a list at the different levels. There the State and Functions are more efficient (with the exception of a Rot that costs 3 bytes more). Not sure what you mean by "state" level. You can't declare variables inside of states; unless you are talking about function/event parameters and local variables to same, but those are not static; ie, they don't persist outside the function / event they are declared within. They should be identical in size to globals; the problem is in measuring them, because the only way to do so is to trigger an event, or call a function, and the overhead of the event/function call plus any parameters tends to skew memory measurements with a low-water-mark function like llGetFreeMemory().
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
05-22-2008 13:14
I like constants rather than hard coding when I can just so I can quickly change things in later editions from a single place. but just like anything else if it's underused as a variable you can save space by hard coding (plus I tend to ingnore constant usage in small/simple scripts because I'm lazy =X to each their own
slight side note: I notice (not as much now) several people got in the habit of using null_key to pad things like link messages(when not using the key field), or (not as bad) using it to test key presence/validity ( better to use just the key since it'll reject invalid/null key )... null key IS a constant (all zeroes with the apropriate dashes) and does take up space...
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
05-22-2008 13:48
I agree. I try to use "constant" variables everywhere I can, because like you say, Void, it makes it a lot easier to change them when you have them all nice and neatly organized at the top of your script.
For a lot of toss-togethers which no one really cares about, especially testers that I will delete afterwards anyway, I don't always follow my own rules about style or efficiency, because that isn't the point of that code.
Agreed also on the use of the NULL_KEY constant. Even though it is technically the most proper to use (esp if keys were actually managed like strange hex numbers instead of strings), I recommend the empty string "", which is valid (and efficient) in most cases of functions.
|
|
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
|
05-22-2008 13:54
/me pokes JIRA. From: VWR-7362 Add LSL constant EMPTY_KEY as (key)"" please Just a minor, minor suggestion to add an LSL constant for an empty key, instead of only having one for a null key, so I don't have to use "" in scripts..
key EMPTY_KEY = ""; key NULL_KEY = "0000-.....-0000";
http://jira.secondlife.com/browse/VWR-7362
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!! - Go here: http://jira.secondlife.com/browse/SVC-1224- If you see "if you were logged in.." on the left, click it and log in - Click the "Vote for it" link on the left
|
|
Shifting Dreamscape
Always questioning ...
Join date: 12 Dec 2007
Posts: 266
|
05-22-2008 17:36
Talrus .. my comment about a state level variable was based on the Wiki where there was a category for Default State variables. First I assumed this meant they could be declared in any state, and the editor I use (LSLEditor) accepted them as valid. Haven't tried in world yet though ...
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
05-22-2008 18:04
From: Shifting Dreamscape Talrus .. my comment about a state level variable was based on the Wiki where there was a category for Default State variables. First I assumed this meant they could be declared in any state, and the editor I use (LSLEditor) accepted them as valid. Haven't tried in world yet though ... It's just a little confusion in semantics. You can declare a variable either globally (before "default"  and it will work for the whole script, including different states OR in an event, but then it will only apply to that one specific event. For example: This works: string variable = "variable";
default { touch_start(integer total_number) { llOwnerSay(variable); } } or this: default { touch_start(integer total_number) { string variable = "variable"; llOwnerSay(variable); } } but this doesn't: default { state_entry() { string variable = "variable"; } touch_start(integer total_number) { llOwnerSay(variable); } } EDIT: But if you change a global variable in any event or even another state then it will be changed for the whole script so that: string variable = "variable"; default { state_entry() { llOwnerSay(variable); } touch_start(integer total_number) { state next; } } state next { state_entry() { variable = "changed"; state default; } }
will return: "temp: variable temp: changed"
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Johan Laurasia
Fully Rezzed
Join date: 31 Oct 2006
Posts: 1,394
|
05-23-2008 02:19
From: Scott Tureaud since lsl is bytecode(for now) ....
A tad off topic, but I had a conversation with Philip Linden today about LSL2 VM, and he stated that there's a large amount of byte code still on the servers, where the original scripts have been deleted, and that there's no way to convert LSL byte code to mono byte code, so, for the time being (probably years), LSL2 VM isn't going anywhere. Seemed to me he was indicating that LSL2 VM will always run along side mono.
|
|
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
|
05-23-2008 05:55
my style:
string function(integer a){string s; //llOwnerSay("function! a does 'this' and is "+(string)a+", b does 'this' and is:"+(string)b) //comment: this function makes little sense but is very small so no detailed explanation is needed if (a>0){do{s+="t";}while (--a);}return s;
that just explains every function right after all variables for that function are declared. The explanation adds memory to the source code, but the shorter variable names gain that back and shorter lines mean more overview. Otionally I remove the // infront of llownersay for function quick debugging. how it does what it is supposed to do is another story, and theres too many different ways to care for each. Sometimes I keep another function that does the same, but with different operators, as a backup in the source code, because it runs faster but needs more bytecode.
|
|
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
|
05-23-2008 06:08
From: Ollj Oh my style:
string function(integer a){string s; //llOwnerSay("function! a does 'this' and is "+(string)a+", b does 'this' and is:"+(string)b) //comment: this function makes little sense but is very small so no detailed explanation is needed if (a>0){do{s+="t";}while (--a);}return s; ...and the lack of whitespace makes it compile faster! The short variable name argument would be easier to buy if you didn't use 'a' for a param that specifies length. Using 'len' really wouldn't have killed you, or at least 'l'.
|