Difference between revisions of "Efficiency Tester"
m (clarify the English - words more short and real - the quick point first, the depth second) |
m (Replaced <source> with <syntaxhighlight>) |
||
(20 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header}} | {{LSL Header}} | ||
Want to see how small some code | '''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: | |||
<pre> | <pre> | ||
//IMPORTANT: Only perform tests in an empty region. | 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 | |||
</pre> | |||
Code: | |||
<syntaxhighlight lang="lsl2"> | |||
// IMPORTANT: | |||
// Only perform tests in an empty region. | |||
// To reduce contamination and be sure to wearing no attachments. | // To reduce contamination and be sure to wearing no attachments. | ||
// Preferably do tests in a private sim with one on it. | // Preferably do tests in a private sim with one on it. | ||
Line 14: | 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. | ||
integer | // (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" | 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 21: | Line 48: | ||
} | } | ||
default { | 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"); | |||
} | |||
} | |||
} | } | ||
</ | </syntaxhighlight> | ||
Launched by [[User:Xaviar Czervik|Xaviar Czervik]], then modified by [[User:Strife Onizuka|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. | |||
{{LSLC|Library}}{{LSLC|Examples}} | {{LSLC|Library}}{{LSLC|Examples}} |
Latest revision as of 01:50, 9 September 2023
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.
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.