[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: ipairs in Lua 5.3.0-alpha
- From: Jan Behrens <jbe-lua-l@...>
- Date: Fri, 15 Aug 2014 18:12:37 +0200
On Fri, 15 Aug 2014 17:31:10 +0200
Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
> On Fri, 15 Aug 2014 16:53:55 +0200
> Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
>
> > I will do further benchmarks on this.
>
>
> I just created a patched Lua 5.3, which differs from Lua 5.3-alpha as
> follows:
>
> --- lua-5.3.0-alpha/src/lbaselib.c 2014-07-24 21:33:29.000000000 +0200
> +++ lua-5.3.0-alpha-staticlen/src/lbaselib.c 2014-08-15 17:17:32.078783582 +0200
> @@ -260,7 +260,11 @@
> */
> static int ipairsaux (lua_State *L) {
> int i = luaL_checkint(L, 2) + 1;
> - if (i > luaL_len(L, 1)) { /* larger than length? */
> + int maxi;
> + lua_settop(L, 2);
> + lua_pushinteger(L, 10000);
> + maxi = luaL_checkint(L, 3);
> + if (i > maxi) { /* larger than length? */
> lua_pushnil(L); /* end traversal */
> return 1;
> }
>
> This is to simulate the length being passed as 3rd argument to
> ipairsaux.
>
> Now I reused my benchmark:
>
> ========================================
> dynamic-length.lua:
>
> datatable = {}
>
> for i = 1, 10000 do
> datatable[i] = tostring(i)
> end
>
> proxytable = setmetatable({}, {
> __index = datatable,
> __len = function() return #datatable end,
> __ipairs = function(t)
> return ipairs(datatable)
> end
> })
>
> local yes = 0
> local no = 0
>
> for i = 1, 10000 do
> for j, v in ipairs(proxytable) do
> if v then yes = yes + 1 else no = no + 1 end
> end
> end
> ========================================
>
>
> Result with the unpatched Lua 5.3-alpha *without* LUA_COMPAT_IPAIRS:
>
> ~/lua_ipairs_test/lua53 % time bin/lua ../dynamic-length.lua
> 114.452u 0.007s 1:55.69 98.9% 259+172k 0+0io 0pf+0w
>
>
> Result with the unpatched Lua 5.3-alpha *with* LUA_COMPAT_IPAIRS:
>
> ~/lua_ipairs_test/lua53compat % time bin/lua ../dynamic-length.lua
> 38.697u 0.000s 0:39.38 98.2% 259+172k 0+0io 0pf+0w
>
>
> Result with the *patched* Lua 5.3-alpha *without* LUA_COMPAT_IPAIRS:
>
> ~/lua_ipairs_test/lua53patched % time bin/lua ../dynamic-length.lua
> 51.611u 0.007s 0:52.27 98.7% 259+172k 0+0io 3pf+0w
>
>
> I would thus conclude that my previously brought up argument in 3. a)
> is valid, but only results in a slowdown of a factor of 1.33
> (51.611 seconds versus 38.697 seconds).
I need to add something here: The factor of 1.33 only applies to my
scenario outlined in the benchmark above, having made the following
assumptions:
* __index points directly to a table (it's not a function)
* __len is a Lua function that applies the # operator to a
global variable
If I modify the benchmark in such way that
* __index is a more expensive Lua function
* __len is a less expensive Lua function (applying the # operator to a
local instead of global variable)
then I get different results.
Here is a new benchmark with these modified assumptions:
========================================
index-func.lua:
local datatable = {} -- local keyword improves performance
for i = 1, 10000 do
datatable[i] = tostring(i)
end
proxytable = setmetatable({}, {
__index = function(t, k) rawget(t, k) end,
__len = function() return #datatable end,
__ipairs = function(t)
return ipairs(datatable)
end
})
local yes = 0
local no = 0
for i = 1, 10000 do
for j, v in ipairs(proxytable) do
if v then yes = yes + 1 else no = no + 1 end
end
end
========================================
With the following results:
~/lua_ipairs_test/lua53 % time bin/lua ../index-func.lua
159.914u 0.000s 2:42.45 98.4% 259+172k 0+0io 0pf+0w
~/lua_ipairs_test/lua53compat % time bin/lua ../index-func.lua
38.443u 0.000s 0:39.01 98.5% 258+172k 0+0io 0pf+0w
~/lua_ipairs_test/lua53patched % time bin/lua ../index-func.lua
96.750u 0.000s 1:37.79 98.9% 259+172k 0+0io 0pf+0w
Removing __ipairs and caching the length (simulated with my patch
above) yields to a slowdown of a factor of 2.52 (96.750 seconds versus
38.443 seconds) in this new example scenario.
Removing __ipairs and not caching the length yields to a slowdown of a
factor of 4.16 (159.914 seconds versus 38.443 seconds) in this new
example scenario.
Regards
Jan