Rules without reasons - SLUniverse Forums
Navigation » SLUniverse Forums > Development Discussion and Support > Scripting » Rules without reasons


Scripting Discuss scripting and programming for SL and other platforms

 
Reply
 
LinkBack Thread Tools Display Modes
Old 06-23-2012, 09:24 PM   #1 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,236
My Mood:
SL Join Date: late 04... that account is deleted now
Rules without reasons

Spotted today over at SLF:
Quote:
Originally Posted by Ela Talaj
There is nothing wrong with do-while() loops just as there is nothing wrong with jump instruction. And yet elegant code tries to avoid either. This applies not only to LSL but to all C-like-syntax languages. There is no loop executed by do-while() that cannot be done (and usually more efficiently) by for() or while()So my advice to you as an admitted beginner is to avoid this construct.
this kind of stuff makes me laugh every time I see it...



any loop can be rewritten as another type of loop... or even as recursion (and vice versa), and while elegant code does try to avoid jumps (not because of what they are, but because they tend to lack clarity), each loop type is optimal to different testing circumstances...


want to take an action and then test the result? do-while


want to test something before taking an action? while(do)


need an intermediary container for comparison with the test? for (which operates on the same principle as while of testing before acting)


in discrete code do-while expects modification (like increments) to happen before the test is done, and usually (but not always) after the actions taken; Recursion expects any incrementation as part of the action. while(do) expects it before the test after the action. and "for" expects it after the test AND the action. Jump has zero expectations on order, it's all down to how it's written, and is considered ambiguous.



all of them can be written to change the order of when incrementation is expected, some even without sacrificing efficiency.


the only real difference is the order things are expected to happen in, and how explicit their limits are... of all of them, "for" is the only one that is truly explicit by itself, but it often has to sacrifice efficiency to realize that goal. otherwise you are forced to know the possible preconditions of the input that's going to be tested. while is considered slightly more explicit than the others, because the test is up front. in large/complex situations these are good things, and improve readability and portability. unfortunately this is where the quoted mythology above comes from. mechanical efficiency != Readability/Portability.


Mechanical efficiency cannot be argued... a thing is either more less or equally mechanically efficient and can be tested empirically. Portability can only be partially argued; some things can be ported, others are intrinsic to their environment (for instance, input requirements for system functions). Readability is largely arguable, because a great deal of it can be reduced to experience and familiarity... these arguments are not without limits though, because it's trivial to write something large an complex enough that even the writer might not recognize it's meaning on looking at it a second time (which is why it's always stressed to document anything that isn't immediately obvious at a glance to the person writing it). Different people WILL come to different conclusions about which is more important based on how they value each consideration.



/rant
__________________
- These eyes can do more than see
Quote:
Originally Posted by Cajsa Lilliehook View Post
It's not enough to care about liberty if the only liberty you care about is your own.
Quote:
Originally Posted by Jupiter Firelyte View Post
Why doesn't anyone ever ask, "What is the real meaning of the winter solstice?"
Quote:
Originally Posted by Eboni Khan View Post
Thanks for being passive agressive.
Void is offline   Reply With Quote
1 User Said Yay!:
1 User Likes This:
Old 06-23-2012, 11:51 PM   #2 (permalink)
Member

*SLU Supporter*
 
Join Date: May 2011
Posts: 30
Not using do {} while in the name of CLARITY?

Because:

bool first = true;
while (first || condition) {
first = false;
...
}

Is so much clearer?

Great post Void.
Tranquillity Dexler is offline   Reply With Quote
2 Users Agreed:
Old 06-24-2012, 03:38 AM   #3 (permalink)
Particle Laboratory Elf
 
Jopsy Pendragon's Avatar
 
Join Date: Nov 2008
Location: Hillcrest, San Diego, USA
Posts: 5,571
My Mood:
SL Join Date: Jan 15 2004
Business: Light Sorcery
I loathe long jumps, for no particular reason other than that my first programming languages were several flavors of GOTO. I mean BASIC. And if I never use another GOTO again, it'll be too soon.

I don't often use do{}while()'s, but I do like having the option. I try to avoid in-lining value assignments in conditionals if I can avoid it. It just gets ugly.

I'm still kinda bummed that LSL doesn't have lazy evaluation of conditionals... as a result a lot of my code ends up looking like:

if ( boolean_variable ) if ( expensive_function() ) { ... }

instead of:

if ( boolean_variable && expensive_function() ) { ... }
Jopsy Pendragon is offline   Reply With Quote
Old 06-24-2012, 03:27 PM   #4 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,236
My Mood:
SL Join Date: late 04... that account is deleted now
lots of us wish for short circuiting (lazy evaluation), but unfortunately, lsl's screwy backwards evaluation order kills it. the reason for that decision was to make the stack logic simpler and faster... if you evaluate them before putting them on the stack in reverse order, you only have to do pure math when you pop them back off in the correct order.... this means the stack sees a little less complexity of use and speeds up operation a fraction and cuts it's size during use, but on the flip side it has some very counter intuitive side effects...

in the statement (A <some math or comparison operator> B) not only do both A and B get evaluated (which isn't wrong), but the value of B is actually determined first. not to much of a big deal if A and B are both variables, but a huge difference if either A or B is a function or assignment that might change the value of something else in your equation.

It does enable some alternate tricks, but because it's so unexpected and counterintuitive compared to other languages and basic mathematical convention, those tricks are definitely not portable, and considered hacks. (Argent and I just had a fun debate about hacks and conventions over in the random picture thread)

as for jumps (goto)? I've always looked at them as being ugly for one main reason... they tend to be used to violate nesting, which in turn tends to violate scope. you can use them with an if statement to do exactly what a loop structure does, and even indent and brace them similarly, and they're well behaved... although in any decent compiler they'd run just the same as the comparable loop structure, so why obfuscate? their only really effective use in my mind is escaping complex error handling to prevent redundant code, it's the one case that favors readability and portability... simple error handling (like quits) can usually be done with a simple if trap statement.


Oddly I really like that LSL is so backwards in many ways, because it forces me to consider the why behind all the long held traditions and conventions in other languages and see where their real merits lie... rather than just assuming X is the right way because it's the way it's always been done. I also get a new appreciation for things like includes, case statements, instant if's, optional parameters, pass by reference, and the like every time something I want to do would be SO much simpler if I had them. Of course it also drives me bonkers when I have to try and work around them... for me LSL is a puzzle that I learn from, the painfully hard way =X
Void is offline   Reply With Quote
1 User Agreed:
1 User Likes This:
Old 06-24-2012, 11:22 PM   #5 (permalink)
Senior Member
 
Join Date: Apr 2012
Posts: 103
My Mood:
SL Join Date: March 2004
do-while uses fewer bytes in LSO.
I loath the for loop (if you use it properly you are wasting CPU time and memory).
I don't like how the while loop is implemented in LSO. It should just be a do-while loop where the first thing you do is jump to the condition, but instead they put the conditional at the top and it jumps from the bottom to the conditional.

That said, in every other language, I use whatever flow control structure is best suited for the situation. For which readability and maintainability are paramount.

The times where I have ended up use a jump it's because LSL lacks Lazy Execution. Or I need to exit a loop. I wish LSL had the "break" keyword, and loop labeling and the "continue" keyword. And switch statements.

Oh and I have only ever used recursion once in LSL. It was for a memory sensitive version of TightListType (it was cheaper in bytecode to use recursions and at that point in the execution I didn't have to worry about running out of memory, but I did later).
Strife is offline   Reply With Quote
2 Users Agreed:
Old 06-25-2012, 07:38 AM   #6 (permalink)
-
 
Imnotgoing Sideways's Avatar
 
Join Date: Jun 2008
Location: Darkly Cute :: Ferguson
Posts: 6,929
My Mood:
SL Join Date: November, 2007
Business: Darkly Cute
Client: NOT the same one I used yesterday... (<.<)
Send a message via Yahoo to Imnotgoing Sideways Send a message via Skype™ to Imnotgoing Sideways
At work, I generally write for Windows apps. I've had no problems following my usual conventions in LSL. But, when I read other peoples' code... Particularly well versed LSL creators... I can't help but notice that many of the conventions they use are similar to coding for an embedded CPU. I'm guessing that's smart, but it is really difficult for me to read. (>_<)
__________________
Link
Imnotgoing Sideways is offline   Reply With Quote
2 Users Hugged You:
1 User Said Thanks:
Old 06-25-2012, 12:57 PM   #7 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,236
My Mood:
SL Join Date: late 04... that account is deleted now
::raises hand::
I'm one of those people that Immy mentions, and she's not wrong (shhh don't tell the silver ferret I said so).

there's two main approaches to any system... write easily readable and understandable code that does not rely on assumptions or side effects and can be easily converted to other system.... or optimize the hell out of it to squeeze every last bit of performance from it, using every oddity to your advantage.

in the former, you code is pretty simple to update, and reusable pretty much anywhere... if you do coding in the real world 99.999% of what you are expected to do is done this way.

in LSL you have severe limits, a dog slow setup, and it's competitively shared, so I approach it from the other angle.... the more optimized my stuff is, and the less resources it uses, the more performance I can squeeze out of the system compared to the next persons stuff, and the better behaved it will be under load... but like a motorcyle in a traffic jam, you have to be really careful, and sometime you can get burnt....

... for instance, at one point, rewriting loops as jump loops was actually faster, and I did it. and then they changed things, because there was a hack that let scripts take extra cpu time with fast jump loops (I didn't use that hack).... I ended up having to go back reconvert all those changes. it wasn't a huge deal, but something I had done to increase performance had actually ended up hurting my performance in the end. I'm a little more careful now of the issue of stability of a hack, but the spectre always looms. for me it's "the road less traveled"... it definitely isn't easier, but it does have it's rewards.
Void is offline   Reply With Quote
Old 06-25-2012, 06:55 PM   #8 (permalink)
Senior Member
 
Join Date: Feb 2012
Posts: 191
Quote:
Originally Posted by Strife View Post
do-while uses fewer bytes in LSO.
I loath the for loop (if you use it properly you are wasting CPU time and memory).
But is it an argue ?
If i ve wanted to do a script with many use of loops , i will compile it in mono not in lso because the loops are 100X to 1000X faster .
And the 3 loops are generally seamless in mono , maybe the "while" loop faster than the "for" loop a, and the both faster than the "do-while" loop .
The differences are very neglectible anyway in Mono

PHP Code:

 
default {
  
state_entry() {

    
float counter;
 
    
//framework variables
    
float i 0;
    
float j 0;
    
float max 1000000;
    
string frame0;
    
string frame1;
    
string frame2
 
    
integer k;
    
llOwnerSay("starting tests");
    for ( 
1<= 10k++)
    {
        
0;
        
0;
        
frame0 llGetEnv("frame_number");
        for (; ++
max; ) ;
        
frame1 llGetEnv("frame_number");
        do ; while (++
max);
        
frame2 llGetEnv("frame_number");
        
float frame_elapsed = (  ((integer)frame1 - (integer)frame0) - ((integer)frame2 - (integer)frame1) );
        if (
frame_elapsed )
        {
            
llOwnerSay("For faster than Do-While , difference (frames) : " + (string)llFabs(frame_elapsed) );
        }
        else
        {
            
llOwnerSay("Do-While faster than For , difference (frames): " + (string)llFabs(frame_elapsed) );
        }
    }
    
llOwnerSay("ending tests");
    
integer used_memory llGetUsedMemory();
    
llOwnerSay((string)used_memory " bytes of memory currently used.");
  }

Result
PHP Code:
[16:45Object: For faster than Do-While , difference (frames) : 3.000000
[16:46Object: For faster than Do-While , difference (frames) : 1.000000
[16:46Object: For faster than Do-While , difference (frames) : 3.000000
[16:46Object: For faster than Do-While , difference (frames) : 4.000000
[16:46Object: Do-While faster than For , difference (frames): 0.000000
[16:46Object: For faster than Do-While , difference (frames) : 11.000000
[16:46Object: For faster than Do-While , difference (frames) : 8.000000
[16:46Object: Do-While faster than For , difference (frames): 1.000000
[16:47Object: Do-While faster than For , difference (frames): 2.000000
[16:47Object: For faster than Do-While , difference (frames) : 9.000000


[16:56Object: For faster than Do-While , difference (frames) : 8.000000
[16:56Object: For faster than Do-While , difference (frames) : 7.000000
[16:56Object: For faster than Do-While , difference (frames) : 2.000000
[16:57Object: For faster than Do-While , difference (frames) : 4.000000
[16:57Object: For faster than Do-While , difference (frames) : 16.000000
[16:57Object: For faster than Do-While , difference (frames) : 10.000000
[16:57Object: For faster than Do-While , difference (frames) : 6.000000
[16:57Object: For faster than Do-While , difference (frames) : 4.000000
[16:57Object: For faster than Do-While , difference (frames) : 7.000000
[16:57Object: For faster than Do-While , difference (frames) : 7.000000 

Last edited by miranda; 06-25-2012 at 07:01 PM.
miranda is offline   Reply With Quote
Old 06-25-2012, 11:10 PM   #9 (permalink)
Senior Member
 
Join Date: Apr 2012
Posts: 103
My Mood:
SL Join Date: March 2004
Quote:
Originally Posted by miranda View Post
But is it an argue ?
If i ve wanted to do a script with many use of loops , i will compile it in mono not in lso because the loops are 100X to 1000X faster .
And the 3 loops are generally seamless in mono , maybe the "while" loop faster than the "for" loop a, and the both faster than the "do-while" loop .
The differences are very neglectible anyway in Mono
I forgot to say, my statement on for loops is specific to LSO. Interesting numbers none the less.
Strife is offline   Reply With Quote
Old 06-26-2012, 02:07 AM   #10 (permalink)
That Bitch

*SLU Supporter*
 
Void's Avatar
Innocent as far as you know
 
Join Date: Nov 2011
Location: Online
Posts: 6,236
My Mood:
SL Join Date: late 04... that account is deleted now
very interesting results... 14mil tests + 7 outputs per minute, works out to about ~233,333.3_ tests per second, or >5,185 tests per frame, including the increment...

not that any considerable variation whould be expected, since both statements (as written) should be literally equivalent instruction wise (LSO is always a suprise =S)

although I do note with amusment that as written, any code in the statements would execute one less time in the for loop than the do loop, and both tests execute 1 less than a million times per overall loop. neither of which affects the test results above, I just thought it was funny
Void is offline   Reply With Quote
Old 06-26-2012, 12:26 PM   #11 (permalink)
Senior Member
 
Join Date: Apr 2012
Posts: 103
My Mood:
SL Join Date: March 2004
Quote:
Originally Posted by miranda View Post
PHP Code:
    integer k;
    
llOwnerSay("starting tests");
    for ( 
1<= 10k++)//proper use of the for loop
    
{
        
0;
        
0;
        
frame0 llGetEnv("frame_number");
        for (; ++
max; ) ;//improper use of the for loop
        
frame1 llGetEnv("frame_number");
        do ; while (++
max);
        
frame2 llGetEnv("frame_number");
    } 
This is exactly what I was talking about. Look at the first for loop in the code, that is how you are supposed to use a for loop. Look at the second for loop, that is precisely how you are not supposed to use a for loop. Of course it's competitive but you might as well use a regular while loop. If you use the for loop properly... especially in LSO it's slower.

To actually test my statement (and address the bug Void pointed out), try:

PHP Code:
    integer k;
    
llOwnerSay("starting tests");
    for ( 
1<= 10k++)
    {
        
frame0 llGetEnv("frame_number");
         
integer i;
         for (
i  0max; ++i) ;
        
frame1 llGetEnv("frame_number");
         
integer j 0;
           do ; while (++
max);
          
frame2 llGetEnv("frame_number");
    } 
Accepted best practices for a for-loop are pretty rigid, your condition isn't supposed to modify the variables used in the loop, you setup the looping variable in the first sub-statement and tweak them after each iteration with the third sub-statement. Do-While loops aren't that rigid.

My point was that best practices and the intended use-cases are at cross purposes with performance.

----

That was a very astute observation Immy. The VM behind LSL has (historically) had more in common (with regards to it's constraints) with embedded systems and computer systems from the 1970's.
For us, we get all excited about a novel idea and then LSL...
Strife is offline   Reply With Quote
Reply

Tags
eternal debates, rant

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On