[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Callables vs functions
- From: "Thiago L." <fakedme@...>
- Date: Thu, 20 Nov 2014 15:03:35 -0200
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))