Difference between revisions of "Efficiency Tester"
(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 | // 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 = | 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 = | 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 = | 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
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
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.