Fixing slow scripts

Creating scripts
User avatar
Ghaelen DLareh
Posts: 76
Joined: Thu Dec 27, 2012 4:13 pm
Has thanked: 49 times
Been thanked: 59 times
Contact:

Re: Fixing slow scripts

Post by Ghaelen DLareh »

Ilan Tochner wrote:Hi Ghaelen,

Top Scripts no longer counts time spent in llSleep but all of Kayaker's recommendations are still very relevant for improving your script performance.

What specifically do you wish to know?
Thanks, Ilan, I am just trying to fingure out how to change the old language phrase to the new language phrase for each and I am aware it takes more than a simple copy/paste.

As a (hopefully) simple example, this is a nice sliding door script from Bob Sutor's tutorials. I'd like to add it sliding door script to the list of scripts here on the forum, but in a way that uses the newer language.

So....

It uses

Code: Select all

 llSetPos(closed_position);           // Move door to closed position
and it should use

Code: Select all

llSetPos(pos); replace with llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,pos]);
but I don't know what the result should look like in this particular script to make that change and still work. I am uncertain as to whether I can just copy and paste one line or if other script lines also need to be changed.



Code: Select all

// Sliding door LSL script #4
// Author Bob Sutor
// Handles the touch event.
// Handles the collision event.
// Handles closing the door automatically via a timer event.
// Triggers sounds when the door opens or closes.

// Parameters you might want to change

float  delay = 3.0;                         // time to wait before 
                                            // automatically closing door
                                           
vector delta = <0.0, 1.0, 0.0>;             // amount to move door 
                                            // when we open it

float  volume = 0.7;                        // 0.0 is off, 1.0 is loudest

// Variables you will most likely leave the same

vector closed_position;                     // original position of the 
                                            // door when closed

key    open_sound  = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
key    close_sound = "e7ff1054-003d-d134-66be-207573f2b535";

// Processing for the script when it first starts up

default {
    // What we do when we first enter this state

    state_entry() {
        closed_position = llGetPos();      // Save position when door is closed
        state closed;                      // Move to the closed state
    }
}

// Processing for the script when it is in the closed state

state closed {
    // What we do when we first enter this state

    state_entry() {
        llTriggerSound(close_sound, volume); // Trigger the sound of the door closing
        llSetPos(closed_position);           // Move door to closed position
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state open;                        // Move to the open state
    }

    // What to do when something hits the door 

    collision_start(integer total_number)
    {
        state open;                        // Move to the open state
    }

    // What to do when the timer goes off

    timer()
    {
        llSetTimerEvent(0.0);              // Set the timer to 0.0 to turn it off
    }
}

// Processing for the script when it is in the open state

state open {
    // What we do when we first enter this state

    state_entry() {
        llTriggerSound(open_sound, volume);// Trigger the sound of the door opening
        llSetPos(closed_position + delta); // Move door to open position
        llSetTimerEvent(delay);            // Set the timer to automatically close it
    }

    // What we do when the door is clicked ("touched") with the mouse

    touch_start(integer total_number) {
        state closed;                      // Move to the closed state
    }

    // What to do when something hits the door 

    collision_start(integer total_number)
    {
        // Do nothing, the door is already open
    }

    // What to do when the timer goes off

    timer()
    {
        llSetTimerEvent(0.0);             // Set the timer to 0.0 to turn it off
        state closed;                     // Move to the closed state
    }
}
A Curative Poison (a metaverse story)

De Landria Rising Market

The De Landria Project
User avatar
Kayaker Magic
Posts: 354
Joined: Sun Dec 01, 2013 8:40 am
Has thanked: 52 times
Been thanked: 393 times

Re: Fixing slow scripts

Post by Kayaker Magic »

Ghaelen DLareh wrote: but I don't know what the result should look like in this particular script to make that change and still work. I am uncertain as to whether I can just copy and paste one line or if other script lines also need to be changed.
I did say that you should NEVER use functions that have a delay, but "moderation in all things". In the case of a door script, the door is only opened and closed occasionally so tying up a server "thread" for 0.2 seconds every once in a long while is not too terrible. There are door scripts that call llSetPos in a loop (thankfully this is not one of them) to make the door move slower and that does make my hair stand on end.
On the other hand, it really is as easy as copy and paste in this case, so you might as well replace llSetPos in just two lines. To be perfectly clear, and to make sure I typed it right, I logged in and made those changes and tried it out. Here is the complete script with those changes:

Code: Select all

    // Sliding door LSL script #4
    // Author Bob Sutor
    // Handles the touch event.
    // Handles the collision event.
    // Handles closing the door automatically via a timer event.
    // Triggers sounds when the door opens or closes.

    // Parameters you might want to change

    float  delay = 3.0;                         // time to wait before
                                                // automatically closing door
                                               
    vector delta = <0.0, 1.0, 0.0>;             // amount to move door
                                                // when we open it

    float  volume = 0.7;                        // 0.0 is off, 1.0 is loudest

    // Variables you will most likely leave the same

    vector closed_position;                     // original position of the
                                                // door when closed

    key    open_sound  = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
    key    close_sound = "e7ff1054-003d-d134-66be-207573f2b535";

    // Processing for the script when it first starts up

    default {
        // What we do when we first enter this state

        state_entry() {
            closed_position = llGetPos();      // Save position when door is closed
            state closed;                      // Move to the closed state
        }
    }

    // Processing for the script when it is in the closed state

    state closed {
        // What we do when we first enter this state

        state_entry() {
            llTriggerSound(close_sound, volume); // Trigger the sound of the door closing
//            llSetPos(closed_position);           // Move door to closed position
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,closed_position]);           // Move door to closed position
        }

        // What we do when the door is clicked ("touched") with the mouse

        touch_start(integer total_number) {
            state open;                        // Move to the open state
        }

        // What to do when something hits the door

        collision_start(integer total_number)
        {
            state open;                        // Move to the open state
        }

        // What to do when the timer goes off

        timer()
        {
            llSetTimerEvent(0.0);              // Set the timer to 0.0 to turn it off
        }
    }

    // Processing for the script when it is in the open state

    state open {
        // What we do when we first enter this state

        state_entry() {
            llTriggerSound(open_sound, volume);// Trigger the sound of the door opening
//            llSetPos(closed_position + delta); // Move door to open position
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,closed_position + delta]); // Move door to open position
            llSetTimerEvent(delay);            // Set the timer to automatically close it
        }

        // What we do when the door is clicked ("touched") with the mouse

        touch_start(integer total_number) {
            state closed;                      // Move to the closed state
        }

        // What to do when something hits the door

        collision_start(integer total_number)
        {
            // Do nothing, the door is already open
        }

        // What to do when the timer goes off

        timer()
        {
            llSetTimerEvent(0.0);             // Set the timer to 0.0 to turn it off
            state closed;                     // Move to the closed state
        }
    }
But then on the third hand, I'm not very fond of this door script. It only works if the door is a separate prim not linked to your house. Once you start using llSetLinkPrimitvieParamsFast, you could switch to PRIM_POS_LOCAL and it should work as a child prim. Or if you are happy with the door as a separate prim you could use llSetKeyframedMotion and control how fast it opens (without using a loop!) On a separate issue, the Gurus of scripting on SL once convinced me that states are not a very useful programming control structure. They are slow (not a big deal in a door) and cause a lot of duplication of code. A script that stores the status of the door in an integer and has only one state is faster, smaller, and easier to understand when you look at it later. States are still useful for other things, like enabling and disabling touch events while running, so it is good to know how to use them and perhaps this door script is a good learning tool.
User avatar
Ghaelen DLareh
Posts: 76
Joined: Thu Dec 27, 2012 4:13 pm
Has thanked: 49 times
Been thanked: 59 times
Contact:

Re: Fixing slow scripts

Post by Ghaelen DLareh »

Kayaker Magic wrote:
Ghaelen DLareh wrote: but I don't know what the result should look like in this particular script to make that change and still work. I am uncertain as to whether I can just copy and paste one line or if other script lines also need to be changed.
I did say that you should NEVER use functions that have a delay, but "moderation in all things". In the case of a door script, the door is only opened and closed occasionally so tying up a server "thread" for 0.2 seconds every once in a long while is not too terrible. There are door scripts that call llSetPos in a loop (thankfully this is not one of them) to make the door move slower and that does make my hair stand on end.
On the other hand, it really is as easy as copy and paste in this case, so you might as well replace llSetPos in just two lines. To be perfectly clear, and to make sure I typed it right, I logged in and made those changes and tried it out. Here is the complete script with those changes:

Code: Select all

    // Sliding door LSL script #4
    // Author Bob Sutor
    // Handles the touch event.
    // Handles the collision event.
    // Handles closing the door automatically via a timer event.
    // Triggers sounds when the door opens or closes.

    // Parameters you might want to change

    float  delay = 3.0;                         // time to wait before
                                                // automatically closing door
                                               
    vector delta = <0.0, 1.0, 0.0>;             // amount to move door
                                                // when we open it

    float  volume = 0.7;                        // 0.0 is off, 1.0 is loudest

    // Variables you will most likely leave the same

    vector closed_position;                     // original position of the
                                                // door when closed

    key    open_sound  = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
    key    close_sound = "e7ff1054-003d-d134-66be-207573f2b535";

    // Processing for the script when it first starts up

    default {
        // What we do when we first enter this state

        state_entry() {
            closed_position = llGetPos();      // Save position when door is closed
            state closed;                      // Move to the closed state
        }
    }

    // Processing for the script when it is in the closed state

    state closed {
        // What we do when we first enter this state

        state_entry() {
            llTriggerSound(close_sound, volume); // Trigger the sound of the door closing
//            llSetPos(closed_position);           // Move door to closed position
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,closed_position]);           // Move door to closed position
        }

        // What we do when the door is clicked ("touched") with the mouse

        touch_start(integer total_number) {
            state open;                        // Move to the open state
        }

        // What to do when something hits the door

        collision_start(integer total_number)
        {
            state open;                        // Move to the open state
        }

        // What to do when the timer goes off

        timer()
        {
            llSetTimerEvent(0.0);              // Set the timer to 0.0 to turn it off
        }
    }

    // Processing for the script when it is in the open state

    state open {
        // What we do when we first enter this state

        state_entry() {
            llTriggerSound(open_sound, volume);// Trigger the sound of the door opening
//            llSetPos(closed_position + delta); // Move door to open position
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION,closed_position + delta]); // Move door to open position
            llSetTimerEvent(delay);            // Set the timer to automatically close it
        }

        // What we do when the door is clicked ("touched") with the mouse

        touch_start(integer total_number) {
            state closed;                      // Move to the closed state
        }

        // What to do when something hits the door

        collision_start(integer total_number)
        {
            // Do nothing, the door is already open
        }

        // What to do when the timer goes off

        timer()
        {
            llSetTimerEvent(0.0);             // Set the timer to 0.0 to turn it off
            state closed;                     // Move to the closed state
        }
    }
But then on the third hand, I'm not very fond of this door script. It only works if the door is a separate prim not linked to your house. Once you start using llSetLinkPrimitvieParamsFast, you could switch to PRIM_POS_LOCAL and it should work as a child prim. Or if you are happy with the door as a separate prim you could use llSetKeyframedMotion and control how fast it opens (without using a loop!) On a separate issue, the Gurus of scripting on SL once convinced me that states are not a very useful programming control structure. They are slow (not a big deal in a door) and cause a lot of duplication of code. A script that stores the status of the door in an integer and has only one state is faster, smaller, and easier to understand when you look at it later. States are still useful for other things, like enabling and disabling touch events while running, so it is good to know how to use them and perhaps this door script is a good learning tool.
Thank you Kayaker. Of course, your last paragraph made my head swim anew. I will study what you've done with the script and then be curious about 'what is better'. This script is ok for what I do right now, and eventually I would like to be able to work with linked prims.
A Curative Poison (a metaverse story)

De Landria Rising Market

The De Landria Project
User avatar
Handy Low
Posts: 231
Joined: Fri Nov 08, 2013 3:38 pm
Location: Yorkshire, England
Has thanked: 207 times
Been thanked: 140 times
Contact:

Re: Fixing slow scripts

Post by Handy Low »

Kayaker Magic wrote:the Gurus of scripting on SL once convinced me that states are not a very useful programming control structure. They are slow (not a big deal in a door) and cause a lot of duplication of code. A script that stores the status of the door in an integer and has only one state is faster, smaller, and easier to understand when you look at it later. States are still useful for other things, like enabling and disabling touch events while running, so it is good to know how to use them and perhaps this door script is a good learning tool.
This is odd, because a few years ago Andrew Linden was recommending using states for performance savings. He checked the SL server code and said that a state change resulted in only one machine instruction - a simple on/off application was more efficient with separate states than with a global variable and "if" tests. Of course, that might not be the case in the OpenSim LSL code, and I'm not about to dive in there to find out ...

I like to use states when appropriate because they help to compensate a little for LSL's lack of dynamically-allocated event handlers. However, while duplication of code in different states can be lessened by the use of functions, if I find that I am duplicating code I'm very likely to bring it all into one state. Duplication is a crime against good programming!
Handy Low
Post Reply