lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi all!

I stumbled a funny result when doing very simple benchmarking on some of my code.

According to the following benchmarks, built-in math.floor and math.ceil are slower than their counterpart rewritten using the core % operator!

Since I found this unlikely, probably my home-brewed benchmarking function is borked, so I'd like some feedback about it.

This is the funny benchmark:

----------------------------------------------------
local StatTime = require 'ld.debug'.StatTime
local function flo( x ) return math.floor( x ) end
local function flo2( x ) return x - x%1 end
local function ce( x ) return math.ceil( x ) end
local function ce2( x ) return x - x%1 + 1 end

print(StatTime(1e8,{ flo, flo2 }, 5.5))  --> 2.4859e-007    1    0.579
print(StatTime(1e8,{ ce, ce2 }, 5.5))    --> 2.6688e-007    1    0.563
----------------------------------------------------

The printed values are:
--> average time of 1st func, 1, relative time of 2nd func



Here below the implementation of StatTime with the relative doc comments (using LDoc - thank you Steve :-)


---------------------------------------------------------
-- Measure the average execution time of a function calling
-- it repeatedly, or compare the relative execution time of a
-- set of functions.
--
-- If `func` is a function, it simply returns the average
-- execution time of the call `func(...)`, where `...` are
-- all the remaining arguments provided to the `StatTime`
-- function.
--
-- If `func` is an array of functions, then `StatTime` will
-- be called individually for each function and the results
-- will be divided by the average execution time of the first
-- element of the array. In this case `StatTime` will return
-- in order:
--
-- + the average execution time of `func[1]` in seconds;
-- + the number `1`;
-- + the average execution time of `func[2]` relative to `func[1]`;
-- + ...
-- + the average execution time of `func[#func]` relative to `func[1]`.
--
-- Relative times will be rounded to 3 decimal digits to
-- improve readability, since more precision is meaningless
-- without an higher accuracy timer (internally `StatTime`
-- uses `os.clock`).
--
-- @function StatTime
-- @param n (**number**) how many times the functions are to
-- be executed to compute the averages.
-- @param func (**function** | **table**) the function or the
-- array of functions to be executed.
-- @param ... the arguments (if any) to use in the function
-- calls.
-- @return the average execution time (see above for the details).
local M_StatTime
do
   local function StatTime( n, func, ...  )
      local t1, t2
      collectgarbage 'collect'
      collectgarbage 'collect'
      collectgarbage 'stop'
      t1 = os_clock()
      for i = 1, n do
         func( ... )
      end
      t2 = os_clock()
      collectgarbage 'restart'
      collectgarbage 'collect'
      collectgarbage 'collect'
      return ( t2 - t1 ) / n
   end

   --[[ local ]]
   function M_StatTime( n, func, ... )
      if type( func ) == 'function' then
        return StatTime( n, func, ... )
      end
      assert( type( func ) == 'table', "#arg2: invalid value type" )
      local times = {}
      local ref_t = StatTime( n, func[ 1 ], ... )
      times[ 1 ], times[ 2 ] = ref_t, 1
      local t
      for i = 2, #func do
         t = StatTime( n, func[ i ], ... ) / ref_t
         times[ i +1 ] = t - t % 0.001
      end
      return unpack( times )
   end
end
M.StatTime = M_StatTime
----------------------------------------------------


Any feedback is welcome.
TIA

-- Lorenzo