Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How to optimize code and when not to.

Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-03-2006 06:57
From: Zepp Zaftig
What would be the point in developing LSL3 rather than just using any of the many languages that work with Mono?
Because the semantic distance between LSL and the Second Life world model is small, so LSL may well remain the most "natural" way to script second life.
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
03-03-2006 07:20
Naturally they would keep the existing LSL working -- LL never breaks existing functionality.

I'm with Strife on this -- If SL supported C, I would write in it. My skills in programming C aren't quite as polished as I'd like, mainly because I rarely have an occasion to write in it. If I wrote C in SL, though, I'm sure my skills would improve.

And then SL could be marketed as immersive programming software-- It's much more fun to program things and sell them for money.

Also, I'm sure we'd all get a bit more exposure to various languages-- reading C, C++, C#, Python..
Zepp Zaftig
Unregistered Abuser
Join date: 20 Mar 2005
Posts: 470
03-03-2006 09:40
From: Ben Bacon
I'd love to use C++ in SL, but I think LL really need to continue supporting scripters who have learned LSL, but do not yet know any RL languages - as well as the large exisiting base of LSL library and open-source code.

IMO, LSL.MONO (or whatever) is a neccesary bridge before LL develop and release a MONO API.


They've already made an LSL compiler that can compile to Mono, and I'm not suggesting that they should stop supporting LSL. I just don't see much point in making a new version of the language itself. I assume that what was meant with LSL3 was a new version of the language itself i.e. changes to the syntax etc. LSL can be kept a simple language like it is and those who want arrays, object oriented programming etc. can use another language instead.

From: Argent Stonecutter

Because the semantic distance between LSL and the Second Life world model is small, so LSL may well remain the most "natural" way to script second life.
LSL is like a state-event driven version of C without arrays, structs, pointers etc., I don't see how that is more natural than anything else. Maybe some people will still prefer LSL, but personally I would much rather use an object oriented language like C#.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-03-2006 10:20
From: Keknehv Psaltery
If SL supported C, I would write in it.
The only C compiler for Mono that I know of is lcc, and it's beta, and the idea of bringing back all the hassles of coding in C in SL is... mind-boggling. Give me Dot-lisp, #Smalltalk, JScript, or Delta-Forth instead.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-03-2006 10:41
From: Zepp Zaftig
LSL is like a state-event driven version of C without arrays, structs, pointers etc., I don't see how that is more natural than anything else. Maybe some people will still prefer LSL, but personally I would much rather use an object oriented language like C#.
LSL is syntactically similar to C but MUCH higher level. Semantically it's got absolutely no resemblance to C whatsoever. Don't get hung up on syntax, you can transform just about any language to and from C-like syntax.

For example:
CODE

variable v
: long_move v ! begin v @ llGetPos llVecDistMag 0.1 < while v @ llSetPos repeat drop ;

define long_move(v) {
while(llVecDist(v, llGetPos) < 0.1) llSetPos(v);
}


Around 1983 I write a preprocessor for Forth called RatForth that would read the C-like code and generate the Forth code above it.

CODE

long_move(v)
real v(3);
real here;
{
llGetPos(here);
while(llVecDist(v,here) < 0.1) {
llSetPos(v);
llGetPos(here);
}
}

SUBROUTINE LONG_MOVE(V)
REAL V(3)
REAL HERE

CALL LLGETPOS(HERE)
10 IF(LLVECDIST(V, HERE) .LT. 0.1) GOTO 20
CALL LLSETPOS(V)
CALL LLGETPOS(HERE)
GOTO 10
20 CONTINUE
END


The former is Ratfor, the latter is the generated Fortran. Again, the Ratfor looks like C, but the Fortran doesn't.

The surface appearance of a language has very little to do with the semantics.
Zepp Zaftig
Unregistered Abuser
Join date: 20 Mar 2005
Posts: 470
03-03-2006 12:06
Argent, what exactly is it about LSL that you think makes it's more natural for SL than other languages?
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-04-2006 15:11
From: Zepp Zaftig
Argent, what exactly is it about LSL that you think makes it's more natural for SL than other languages?


I'll answer this; we already have LSL.

I'm not advocating a single Mono compatible language. I'd like to pick and choose.

As to LSL3 I don't see the point in developing it, I don't see LL making LSL better.

BTW we are straying off topic
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Zepp Zaftig
Unregistered Abuser
Join date: 20 Mar 2005
Posts: 470
03-04-2006 18:43
From: Strife Onizuka
I'll answer this; we already have LSL.

I'm not advocating a single Mono compatible language. I'd like to pick and choose.

As to LSL3 I don't see the point in developing it, I don't see LL making LSL better.

BTW we are straying off topic

Aye, I can agree to that.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-04-2006 19:13
From: Zepp Zaftig
Argent, what exactly is it about LSL that you think makes it's more natural for SL than other languages?
It's event-driven and lightweight, and the state mechanism works well... in a way, it's describing a grammar for parsing an event stream from LL. You could use other languages, but they're either low level (like C or C++) or they have a lot of overhead that's inappropriate for a real-time language. For example, LSL can perform brute-force garbage collection when it returns to the event level, because at that point there's no references that need to be traced... everything is in globals.

About the only things I'd like to add to LSL are arrays that can be passed by reference, like in Tcl or C. I don't want to see arrays of arrays or pointers to anything, because that complicates the garbage collection immensely... once you get back to the top level you need to be reference-free.
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
03-04-2006 19:58
You have a point, Argent. But LSL is, of course, missing some basic lower-level functionalities that many find useful-- arrays being the most notable ones, with various other more fiddly things missing.

LSL gets close, but it's still missing things in C that are really useful. If they made LSL3 to be a hybrid between the current LSL and C, keeping the state/event structure but allowing lower-level manipulation, then I might consider using it.

What would be really neat would be some sort of Mono assembly language-- then we can have hyper-optimized scripts to factor RSA-1024 (That was a joke).

Assembly would be useful, because if the language(s) are missing a feature, you can say "Ah, well, I guess I'll just have to do this the long way..."

Databases anyone?
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
03-04-2006 20:42
What C features would you add? I wouldn't touch pointers/malloc/free with a 10' pole here - too much chance for errors or malicious code, so elaborate policing/bounds checking would have to be added to the VM.

Arrays for sure. User-definable data types would be nice. Very nice. And arrays... if lists had much lower overhead and allowed direct access to individual elements without an O(n) lookup for every llList2... call (which I believe is how things are now). But I guess it would be simpler to give us arrays, since there's no real way to implement that.

Switch-case? Unless they implement it as a jump table, the compiler will expand that out into if-else blocks, so all you gain is code readability.

Something I've wished for a few times - the ability to specify a state name in a variable. So you could change states by calling "state varName;". I think that would be pretty powerful, and useful, it would let us streamline a lot of decision/input based state changes.

And my latest annoyance - to not have a 400 character string take up 800 bytes of memory. And more memory is always nice :) Hmm... databases. Access to a mySQL-ish API, with persistent storage. That would be awesome, since I think most scripts that hit the memory limit do so because they're trying to store data. I have no idea how hard this would be to do. And how much it would hit the asset server. Maybe it could be done outside the asset server.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-05-2006 05:17
From: Keknehv Psaltery
You have a point, Argent. But LSL is, of course, missing some basic lower-level functionalities that many find useful-- arrays being the most notable ones, with various other more fiddly things missing.
Sure, but it does have all the basic data types and controls (for example, vectors and events) that SL needs as primitives. Any language that was going to be as well suited to SL would also have to have these data types as primitives, or every script would have to include or import code to re-implement them... adding to the complexity AND size of the script and (for a given implementation technology) you'd likely end up with slower code because people would fill in the blanks in different ways... and there aren't any that exactly fit. So LSL, or an LSL derivative, is still desirable.

I wouldn't want a hybrid between LSL and C. C is completely inappropriate for the target audience... bringing in traditional arrays, associative arrays, Lisp-style lists, or some other non-referenceable but handle-based "collection" object is the biggest need, because all the copying that the current implementation requires is the main thing that's killing it now.
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
03-05-2006 08:39
One thing I found in my 12 script monster of a vendor, breaking up code into seperate scripts actually has a positive effect on overall speed.

So if your code allows it you can do things like:

CODE
touch_start(integer x) {
// Do some stuff
// Load some info from a list
// Do some more stuff
}


Replaced with:

CODE
touch_start(integer x) {
// Do some stuff
// Send a link message to another script (which holds the list)
}

link_message(integer link_num, integer num, string message, key id) {
// Do some more stuff
}


This runs significantly faster in my case, not to mention that it reduced memory useage by about 30k using multiple scripts to hold the list as separate chunks :)

On that note, if you are storing data in some kind of pattern, then breaking a big list down into several smaller lists is a good move.
For example, I have a vendor with 50 items, entered in the order they are read from the notecard.
I convert this list into 5 smaller lists of 10. Knowing the maximum size of each list I can happily load an item, e.g if I want item number 25 then I just divide by 10 and round up, which tells me that the item is in list #3.
If I am using link-messaged scripts to hold the lists then addressing this list is extremely easy provided each list listens for link messages containing a particular integer, in this case the number 3.
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
03-05-2006 10:43
From: Keknehv Psaltery
What would be really neat would be some sort of Mono assembly language
The client compiles to CIL and sends that to the simulator. Babbage says you could use CIL right now if the client didn't try to compile it.

Since it would be trivial to "hack" it and send whatever CIL you want, maybe they will have the assembler and VM secure (Mono does most of the work), and open up CIL to everyone. Then you could use whatever language you want, without the client having to support it. I wouldn't count on it though. Any of it.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-15-2006 08:09
From: Strife Onizuka


Instead of useing ZERO_VECTOR or ZERO_ROTATION or even a global variable storing them.
Use ((rotation)"";)
and ((vector)"";)
they each cost 4 bytes :D
Which is less then it takes to push a value into the stack. :cool:

This is the point that using ESL rocks. Simple way to shave a few bytes.
CODE

//ESL
#define ZERO_VECTOR ((vector)"")
#define ZERO_ROTATION ((rotation)"")


You can also do this with integers and floats, saving 1 byte.

CODE

//ESL
#define ZERO_VECTOR ((vector)"")
#define ZERO_ROTATION ((rotation)"")
#define ZERO_FLOAT ((float)"")
#define ZERO_INTEGER ((integer)"")

what i didn't mention, that this is actualy slower.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Kermitt Quirk
Registered User
Join date: 4 Sep 2004
Posts: 267
Evaluation of if's
03-20-2006 04:51
OK... here's something I've always wondered. If the first part of an if statement is false, will LSL still evalute the entire if statement? I've seen diff languages deal with this both ways.

For example... Will the "b == c" part be evaluated in this?
CODE
integer a = 1;
integer b = 2;
integer c = 3;

default {
state_entry() {
if(a == b && b == c)
do_something();
}
}


If it would, then this would probably run faster. (Although I assume it'd use more space on the stack)
CODE
integer a = 1;
integer b = 2;
integer c = 3;

default {
state_entry() {
if(a == b) {
if (b == c)
do_something();
}
}
}
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-20-2006 05:18
It will execute the entire argument even if it is false.

From: Kermitt Quirk
If it would, then this would probably run faster. (Although I assume it'd use more space on the stack)


It would be faster if the first were false, but otherwise slower if the first were true. Splitting it adds 4 bytes to the bytecode.

If the first argument is false more often then true, then there will be some proformance gains.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Kermitt Quirk
Registered User
Join date: 4 Sep 2004
Posts: 267
03-20-2006 05:29
From: Strife Onizuka
It will execute the entire argument even if it is false.

It would be faster if the first were false, but otherwise slower if the first were true. Splitting it adds 4 bytes to the bytecode.

If the first argument is false more often then true, then there will be some proformance gains.


Good. That's exactly what I expected. Because of that I tend to nest things, especially if the second part of the if is a function call, so at least now I know it's worth continuing.
Sky Honey
Coder
Join date: 16 May 2005
Posts: 105
03-20-2006 05:31
Darn, Strife beat me. Well anyway:
CODE
integer test() {
llOwnerSay("test");
return TRUE;
}
default {
state_entry() {
if (1 == 1 && test() == TRUE) {
llSay(0, "Hello, Avatar!");
}
}
}

output:
Object: test
Object: Hello, Avatar!
_____________________
Johntron Thirty
Registered User
Join date: 4 Mar 2005
Posts: 24
Code kung foo
03-20-2006 14:58
Wow, this post is way too drawn out. I think we should just ask LL to auto-optimize the code at compile time and be done with it.
lyndell Aleixandre
Registered User
Join date: 17 Oct 2005
Posts: 5
03-26-2006 09:53
Pffft.... like that will ever happen .. lmao
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
03-26-2006 10:51
From: Johntron Thirty
Wow, this post is way too drawn out. I think we should just ask LL to auto-optimize the code at compile time and be done with it.
They could at least reference-count lists and strings instead of actually copying them all the time.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
08-17-2006 21:29
It's been a while, and i have a few optimizations i haven't posted yet.

To start things off, a replacement for llGetListLength that is 15% faster.
CODE

integer len = llGetListLength(a);
//becomes
integer len = (a != []);
//savings: 12 bytes and 15% faster (12 bytes is 2/3's of the function call; this is a huge savings)

//and if you were using
integer nlen = -llGetListLength(a);
//becomes
integer nlen = ([] != a);
//savings: 14 bytes and 15% faster


CODE

integer c;
(++c)
//or
(c+=1)
//Can be replaced with:
(c=-~c)
//Its executes in the same time and saves 4 bytes.

//If you want to replace
(--c)
//or
(c-=1)
//Can be replaced with:
(c=~-c)
//like above, 4 byte savings and same execution speed.


CODE

#define MMi(i) (i=~-i)
#define PPi(i) (i=-~i)
#define llGetListLength(a) (a != [])
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Bobbyb30 Zohari
SL Mentor Coach
Join date: 11 Nov 2006
Posts: 466
01-15-2007 17:47
rotation a = <0,0,0,1>;//1
//becomes... and saves 8 bytes
rotation b = <0.0,0.0,0.0,1.0>;//2

so rotation a takes more space than rotation b?

Just curious but would the placement of {}'s affect a scripts speed/memmory?
Would Ex:1 run slower than ex:2?

Ex:1
default
{
state_entry()
{
llSay(0, "Hello, Avatar!";);
}

touch_start(integer total_number)
{
llSay(0, "Touched.";);
}
}

Ex:2
default
{
state_entry(){
llSay(0, "Hello, Avatar!";);
}

touch_start(integer total_number){
llSay(0, "Touched.";);
}
}
Bobbyb30 Zohari
SL Mentor Coach
Join date: 11 Nov 2006
Posts: 466
01-15-2007 17:52
From: Strife Onizuka
You can also do this with integers and floats, saving 1 byte.

CODE

//ESL
#define ZERO_VECTOR ((vector)"")
#define ZERO_ROTATION ((rotation)"")
#define ZERO_FLOAT ((float)"")
#define ZERO_INTEGER ((integer)"")

what i didn't mention, that this is actualy slower.


1 byte?
Are we that desperate to get 1 byte?
1 2 3 4