Difference between revisions of "Efficiency Tester"

From Second Life Wiki
Jump to navigation Jump to search
(link directly with Code Sizer -- was merely alluding cryptically to the brief & clear & conventional (though neither small nor fast) harness for llGetFreeMemory that that article now presents)
(change to llGetTime from llGetTimestamp, sneer LOUDLY at any result measured while time visibly ran backwards)
Line 21: Line 21:
// There is a margin of error so run the tests multiple times to determine it.
// There is a margin of error so run the tests multiple times to determine it.


integer time() { // count milliseconds since the day began
// Measure the race instead
// in calendar milliseconds elapsed since the day began,
// if called in place of llGetTime.
 
integer getTime() // count milliseconds since the day began
{
     string stamp = llGetTimestamp(); // "YYYY-MM-DDThh:mm:ss.ff..fZ"
     string stamp = llGetTimestamp(); // "YYYY-MM-DDThh:mm:ss.ff..fZ"
     return (integer) llGetSubString(stamp, 11, 12) * 3600000 + // hh
     return (integer) llGetSubString(stamp, 11, 12) * 3600000 + // hh
Line 28: Line 33:
}
}


default {
default
     state_entry() {
{
     state_entry()
    {


         // always measure how small, not only how fast
         // always measure how small, not only how fast
Line 53: Line 60:
             // begin
             // begin


             float t0 = time();
             float t0 = llGetTime();


             // loop to measure elapsed time to run sample code
             // loop to measure elapsed time to run sample code
Line 66: Line 73:
             } while (++i < max);
             } while (++i < max);


             float t1 = time();
             float t1 = llGetTime();


             // loop to measure elapsed time to run no code
             // loop to measure elapsed time to run no code
Line 72: Line 79:
             do ; while (++j < max);
             do ; while (++j < max);


             float t2 = time();
             float t2 = llGetTime();


            // complain if time ran backwards
           
            if (!((t0 <= t1) && (t1 <= t2)))
            {
                llOwnerSay("MEANINGLESS RESULT -- SIMULATED TIME RAN BACKWARDS -- TRY AGAIN");
            }
           
             // report average time elapsed per run
             // report average time elapsed per run



Revision as of 06:43, 20 October 2007

Q1: Want to see how small some code compiles?

A: See the Code Sizer harness for llGetFreeMemory.

Q2: Want to discover quickly if a change to code makes the code run faster?

A: See the Code Racer harness for llGetTimestamp.

Q3: Want to see approximately how fast some code runs?

A: Run your code inside code like this example to call your code time and again to measure the consequent change in llGetTimestamp.

// IMPORTANT:
// Only perform tests in an empty region.
// To reduce contamination and be sure to wearing no attachments.
// Preferably do tests in a private sim with one on it.
// Don't move while performing the test.
// There is a margin of error so run the tests multiple times to determine it.

// Measure the race instead
// in calendar milliseconds elapsed since the day began,
// if called in place of llGetTime.

integer getTime() // count milliseconds since the day began
{
    string stamp = llGetTimestamp(); // "YYYY-MM-DDThh:mm:ss.ff..fZ"
    return (integer) llGetSubString(stamp, 11, 12) * 3600000 + // hh
           (integer) llGetSubString(stamp, 14, 15) * 60000 +  // mm
           llRound((float)llGetSubString(stamp, 17, -2) * 1000000.0)/1000; // ss.ff..f
}

default
{
    state_entry()
    {

        // always measure how small, not only how fast

        llOwnerSay((string) llGetFreeMemory() + " free bytes of code at default.state_entry");

        // always take more than one measurement

        integer repeateds;
        for (repeateds = 0; repeateds < 3; ++repeateds)
        {

            // declare test variables

            float counter;

            // declare framework variables

            float i = 0;
            float j = 0;
            integer max = 10000; // 2ms of work takes 20 seconds to repeat 10,000 times, plus overhead

            // begin

            float t0 = llGetTime();

            // loop to measure elapsed time to run sample code

            do
            {

              // test once or more

              counter += 1;
      
            } while (++i < max);

            float t1 = llGetTime();

            // loop to measure elapsed time to run no code

            do ; while (++j < max);

            float t2 = llGetTime();

            // complain if time ran backwards
            
            if (!((t0 <= t1) && (t1 <= t2)))
            {
                llOwnerSay("MEANINGLESS RESULT -- SIMULATED TIME RAN BACKWARDS -- TRY AGAIN");
            }
            
            // report average time elapsed per run

            float elapsed = ((t1 - t0) - (t2 - t1))/max;
            llOwnerSay((string) elapsed + "+-25% may have passed on average in each of");
            llOwnerSay((string) max + " trials of running the code in the loop");
        }
    }
}

Launched by Xaviar Czervik, then modified by Strife Onizuka, then further edited as the history of this article shows.

Try the empty test of deleting the { counter += 1; } source line to see the astonishing inaccuracy of this instrument. The time cost of no code, as measured here, isn't always zero!

See the LSL Script Efficiency article for a less brief discussion. Please understand, we don't mean to be arguing for many different ways to measure the costs of code. Here we do mean to be building a consensus on best practices, in one considerately short article constructed from a neutral point of view.