Difference between revisions of "Efficiency Tester"

From Second Life Wiki
Jump to navigation Jump to search
(report ms of llGetTime rather than s, more like the legacy of ms of llGetTimestamp)
m (quote byte code size as commented, not the raw llGetFreeMemory result)
Line 34: Line 34:
// 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.


// (15267 - 18) was the well-known byte code size of this llGetTime/ llGetTimestamp harness
// (16384 - (15267 - 18)) was the well-known byte code size of this llGetTime/ llGetTimestamp harness


// Measure the race instead
// Measure the race instead

Revision as of 10:11, 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.

Sample Results:

15249 free bytes of code at default.state_entry
0.177314+-??% ms may have elapsed on average in each of
10000 trials of running the code in the loop
0.176341+-??% ms may have elapsed on average in each of
10000 trials of running the code in the loop
0.201925+-??% ms may have elapsed on average in each of
10000 trials of running the code in the loop

Code:

// 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.

// (16384 - (15267 - 18)) was the well-known byte code size of this llGetTime/ llGetTimestamp harness

// 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; // 18 bytes is the well-known byte code size of this sourceline
      
            } 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 elapsedms = 1000.0 * (((t1 - t0) - (t2 - t1)) / max);
            llOwnerSay((string) elapsedms + "+-??% ms may have elapsed 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.