lua-users home
lua-l archive

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



On 20/11/14 01:33 PM, Jerome Vuarand wrote:
2014-11-19 21:26 GMT+00:00 Thiago L. <fakedme@gmail.com>:
<SoniEx2> %5.3 t=setmetatable({")", "'test'", "print("},{__call =
function(t,...) return table.remove(t) end}) load(t)()
<yalb> SoniEx2: sandbox:1: bad argument #1 to 'load' (function expected, got
table); stack traceback:; [C]: in function 'load'; sandbox:1: in main chunk

Can we please get a callable API? (for example, iscallable(obj), or in C,
lua_iscallable(whatever))
You can always wrap a callable in a function, and a function is both
type-testable and always callable. So if you need a testable callable,
just wrap your object in a function. Given how easy that solution is,
you'll need more than a "please" to get that kind of feature. Where
are use cases, stats, benchmarks?

Ok so...

Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> t = setmetatable({},{__call = function(...) end})
> c = os.clock() for i=1, 10000 do t() end print(os.clock()-c)
0.000986
> c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
0.001934

(Well ok, a real use case would be a bit bigger than that, this is just an example, as in this case you can just cache the wrapper into a local)

With locals instead:

> local t = setmetatable({},{__call = function(...) end}); c = os.clock() for i=1, 10000 do t() end print(os.clock()-c); c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
0.000421
0.001224

Cache table:

> local t = setmetatable({},{__call = function(...) end}); local cache = setmetatable({},{__index = function(t,k) rawset(t,k,function(...) return k(...) end) return t[k] end}); c = os.clock() for i=1, 10000 do (function(...) return t(...) end)() end print(os.clock()-c); c = os.clock() for i=1, 10000 do cache[t]() end print(os.clock()-c)
0.001449
0.001639

(Lua 5.2 does wonders there!)

LuaJIT - globals:

LuaJIT 2.0.3 -- Copyright (C) 2005-2014 Mike Pall. http://luajit.org/
JIT: ON CMOV SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse
> t = setmetatable({},{__call = function(...) end}); c = os.clock() for i=1, 10000 do t() end print(os.clock()-c); c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
4.7e-05
0.000871

LuaJIT - locals:

> local t = setmetatable({},{__call = function(...) end}); c = os.clock() for i=1, 10000 do t() end print(os.clock()-c); c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
5e-05
0.001203

(LuaJIT is too good at optimizing global access)

LuaJIT - cache:

> local t = setmetatable({},{__call = function(...) end}); local cache = setmetatable({},{__index = function(t,k) rawset(t,k,function(...) return k(...) end) return t[k] end}); c = os.clock() for i=1, 10000 do (function(...) return t(...) end)() end print(os.clock()-c); c = os.clock() for i=1, 10000 do cache[t]() end print(os.clock()-c)
0.001503
7.3e-05

Now, we tested Lua 5.2 and LuaJIT, what about Lua 5.1?

Lua 5.1 - Globals:

Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> t = setmetatable({},{__call = function(...) end}); c = os.clock() for i=1, 10000 do t() end print(os.clock()-c); c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
0.002817
0.004132

Lua 5.1 - Locals:

> local t = setmetatable({},{__call = function(...) end}); c = os.clock() for i=1, 10000 do t() end print(os.clock()-c); c = os.clock() for i=1, 10000 do (function(...) t(...) end)() end print(os.clock()-c)
0.003736
0.005732

Lua 5.1 - Cache:

> local t = setmetatable({},{__call = function(...) end}); local cache = setmetatable({},{__index = function(t,k) rawset(t,k,function(...) return k(...) end) return t[k] end}); c = os.clock() for i=1, 10000 do (function(...) return t(...) end)() end print(os.clock()-c); c = os.clock() for i=1, 10000 do cache[t]() end print(os.clock()-c)
0.003418
0.002866

(I'm surprised by how this turned out - Lua 5.2 faster than Lua 5.1 even tho Lua 5.1 doesn't index a local to get access to globals?! - so if you want real examples go check out Minetest mods :P (yes they are that bad))