Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Variable Efficiencies

Nexus Laguna
Registered User
Join date: 20 Dec 2006
Posts: 40
04-11-2007 03:27
I have done some preliminary testing on which variables are the most memory and speed efficient to use in scripts. While some of the results seem to be common sense, some scripters may not realise the true impact of the different variable types on script efficiency.

I have also outlined ways of using the more efficient types in your scripts.

The one thing to remember is that certain data types are a necessity at times and you don't really have a choice as to when to use them. By these I am referring to the vector and rotation types. The list type is also, at times, a necessity, but there are times when a list is not necessarily required. As such I only tested the integer, float, string and list types. The following list orders these types into their efficiency and the likely explanation why:

- Integer: Most efficient. This is due to the fact that integers use the smallest amount of memory per variable as well as the fact that calculating whole numbers is a lot quicker for a CPU than any other type.

- Float: Float types should be avoided where integers can do the job instead. Floats tend to require more memory than integers and calculation of floats is more CPU intensive than an integer type.

- String: Because a string is made up of characters, and each character consuming 16 bits, these can be large memory hogs. Also, when strings are concatenated (joining two strings together), the normal procedure for processing a concatenation is to create a new temp string variable, then add the two strings into that, then copy the value into the actual string variable you want it stored in and then the temp variable being deleted. This is very CPU intensive again.

- Lists: Lists are difficult to determine, as they can be filled by integers, floats, string, vectors and rotations, or a combination of them all. Generally the variables stored in the list affect its efficiency... BUT .... one thing to remember is that a list with one integer is more memory and CPU intensive than an integer alone as the creation and management of a list adds extra processing overhead.

So heres some tips to help you make more efficient scripts through the proper use of variable types:

- If you create a flag variable in your script, try to keep it as an integer. For example, if you want to record in a script which menu/sub-menu (llDialog) you are accessing, try using an integer with a specific number for each menu instead of a string. So, the first menu can be 0, the second one can be 1, the third one can be 2, instead of the first one being "Main", the second one being "Sub Menu 1" the third being "Sub Menu 2", etc.

- When using floats, look properly at the type of data that the float will contain. Do you expect there to ever be fractions? For example, if you are dealing with money, there are NEVER Linden cents. You cannot pay someone a fraction of a Linden Dollar, so anything to do with money calcualtions should always be kept as an integer. There are many situations like this.

- Use lists sparingly. Sometimes it might seem to be the best way to store data but often there is an alternative. One alternative is a string. Instead of storing, for example, the details of a purchase someone has made into a list like ["Name", "Date", "Item"], you can instead use a string like "Name*Date*Item" and then use the llParseString2List function later like this:

list_name = llParseString2List(combined_string, ["*"], [""]);

Again though you also need to weigh whether you will be doing this very often as this method could end up being worse if you would access llParseString2List too often.

Also, when you are done with a list, empty it. This is easily done by using list_name = [];. An empty list still consumes some resources, but far less than having one full of data you no longer need.

I hope that some find this useful. If not, feel free to comment and add your own experiences of variable efficiency as well :)
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
04-11-2007 08:55
From: Nexus Laguna
- Integer: Most efficient. This is due to the fact that integers use the smallest amount of memory per variable as well as the fact that calculating whole numbers is a lot quicker for a CPU than any other type.


While this may be true at the instruction cycle level (and only a very small margin of difference with today's CPUs), the overall impact of using integers vs floats is negligible compared to the overhead inherent in the scripting language for using any scalar variable.

From: someone
- Float: Float types should be avoided where integers can do the job instead. Floats tend to require more memory than integers and calculation of floats is more CPU intensive than an integer type.


This is incorrect. Floats are IEEE "Single"-sized and thus consume the exact same amount of memory as the integer type: 4 bytes + overhead.

From: someone
- String: Because a string is made up of characters, and each character consuming 16 bits, these can be large memory hogs.


This is also incorrect. LSL current only uses UTF-8, which means 8 bits (or 1 byte) per character.

From: someone
Also, when strings are concatenated (joining two strings together), the normal procedure for processing a concatenation is to create a new temp string variable, then add the two strings into that, then copy the value into the actual string variable you want it stored in and then the temp variable being deleted. This is very CPU intensive again.


This is true, but I am not sure why it is relevant. Strings are for what strings are for. You can't just arbitrarily decide to store string data in a float because it is "more efficient". You *can* use strings for holding other types, but since manipulating them requires you to convert them to the correct type beforehand, this is rarely useful for the purposes of "increasing efficiency".

From: someone
- Lists: Lists are difficult to determine, as they can be filled by integers, floats, string, vectors and rotations, or a combination of them all. Generally the variables stored in the list affect its efficiency... BUT .... one thing to remember is that a list with one integer is more memory and CPU intensive than an integer alone as the creation and management of a list adds extra processing overhead.


In general, the size of the variable slightly affects the efficiency of list element processing, because it has to be copied at some point to be used. Outside of that, the variable's type has no other effect on list efficiency. Also, all but one variable type consumes more memory (5 bytes per instance) when stored on a list.

One curiosity to note is that strings stored on a list actually use up less memory than if stored in separate string variables. However, it takes 4+ strings stored in the list to realize that savings, due to the list variable overhead. Also, processing/access time is increased, and handling large lists of strings can get you into memory trouble quicker.

From: someone
- If you create a flag variable in your script, try to keep it as an integer.


Even better, pack multiple flags into one integer and use bitwise operators to manipulate them. Trading speed for space, but not by much. :)

From: someone
- When using floats, look properly at the type of data that the float will contain. Do you expect there to ever be fractions? For example, if you are dealing with money, there are NEVER Linden cents. You cannot pay someone a fraction of a Linden Dollar, so anything to do with money calcualtions should always be kept as an integer. There are many situations like this.


It's probably better to determine this by the type of calculation than simply by the result type. For example, let's say you had to divide a payment up among several people. Doing a completely integer calculation will result in integer rounding errors and, for small values relative to the number of receivers, will cause some folks to get nothing. Therefore, it is appropriate to do the calculations with floats, and then finish up with llRound, llCeil, llFloor, or just simply casting to (integer).

From: someone
- Use lists sparingly. Sometimes it might seem to be the best way to store data but often there is an alternative. One alternative is a string. Instead of storing, for example, the details of a purchase someone has made into a list like ["Name", "Date", "Item"], you can instead use a string like "Name*Date*Item" and then use the llParseString2List function later like this:

list_name = llParseString2List(combined_string, ["*"], [""]);


This is good advice. Lists are awful for most things, but they really can't be beat for large-scale storage of variables. Just know that using something other than lists (strings in your example) trades memory usage for processor usage (though not by much, really).

From: someone
Also, when you are done with a list, empty it. This is easily done by using list_name = [];. An empty list still consumes some resources, but far less than having one full of data you no longer need.


More good advice. You can even use this as a trick to prevent over-usage of memory when you add elements to a list, hence:

mylist = (mylist=[]) + mylist + [newelement];

This prevents at least one extra copy of the list from appearing on the stack and, for large list handling, allows much larger lists to be made before getting the dreaded stack/heap error.

For some more detailed analysis of memory usage by variables I recommend:
http://www.lslwiki.net/lslwiki/wakka.php?wakka=MemoryUsage