Stopwatch by sorcerykid

Stopwatch is Lua-based benchmarking API for Minetest developers

115 downloads

Stopwatch is a utility for developers to very quickly benchmark portions of Lua code, but without the complexity and overhead of enabling the mod profiler. I created this mod because my code was becoming littered with far too many time-keeping calculations while debugging. It should be fully compatible with all versions of Minetest 0.4.x+ since it only depends on the monotonic clock function.

For the latest release notes, as well as technical support requests, please visit the forum topic.

Installation

  1. Unzip the archive into the mods directory of your subgame
  2. Rename the stopwatch-master directory to "stopwatch"
  3. Add "stopwatch" to the depends.txt file of mods using the Stopwatch API.

Usage Instructions

You will first need to create a Stopwatch object at the top of the mod that you want to benchmark. The constructor accepts four parameters: a unique identifier for the test series (required), the output color of the results (default is "white"), the numeric scale of each value (default is "ms"), and the numeric precision of each value (default is 3)

local S, S_ = Stopwatch( id, color, scale, prec )

After initializing its internal state, the constructor returns two functions that can be used to benchmark your code.

S( )

S_( is_show )

The S( ) function starts a new trial for the given test series, and the S_( ) function stops the current trial, outputting the elapsed execution time if is_show is true. When the server is shutdown, the total elapsed time for the test series will be output in addition to a variety of other statistics:

A new Stopwatch object should be instantiated for each additional benchmark that you wish to perform. In addition, you will want to append digits or some other unique signifier to distinguish the corresponding start and stop functions.

In this example, I'm measuring the performance of Lua's table.insert function in append vs. prepend mode:

local S1, S1_ = Stopwatch("table_prepend")
local S2, S2_ = Stopwatch("table_append")

local y = { }
S1( )
for x = 0, 5000 do
        table.insert( y, 1, x )
end
S1_( )

y = { }
S2( )
for x = 0, 5000 do
        table.insert( y, x )
end
S2_( )

The output should look something like this.

By performing multiple iterations, it is possible to get a more representative sample for each trial.

It is worth noting that Lua's print( ) function tends to be somewhat CPU intensive. Therefore you should avoid outputting the per-trial execution times for nested test series, otherwise the results will be skewed. For linear test series, such instrumentation overhead is less a concern since the execution times are already calculated prior to being output.

However, depending on the time-sensitive nature of your routines, you should still be mindful of this caveat.