So, a bit of a primer as to how Lua works, which I'm kind of paraphrasing Roberto from the book Lua Gems. Local is fastest, because it's stored in one of Lua's registers. There's about 200 of them, so don't overuse the local keyword, or keep your functions small. _G is in an implied register, so looking up _G and a register are equally fast. Top level libraries are contained in _G's table, so _G["math"] is slower than math being localized, because it involves a table lookup. math["min"] requires two table lookups and a register lookup. So, before we even get to the functions, lowest is doing better than math.min because of one less table lookup. Localize math.min, which a lot of people do, and the lookups get bypassed.
Now, for the real meat of why math.min is slower, is because this is how math.min is implemented:
Code: Select all
static int math_min (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmin = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d < dmin)
dmin = d;
}
lua_pushnumber(L, dmin);
return 1;
}
There's a loop, and this luaL_checknumber API call is verifying the arguments. The proper lua implementation of min would be this:
Code: Select all
function min(dmin, ...)
assert(type(dmin)=="number")
local N = select('#', ...)
for i = 1, N do
local d = select(i, ...)
assert(type(d)=="number")
if d < dmin then dmin = d end
end
return dmin
end
Jasoco's lowest function is faster because it does less.