[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Lua 5.3.4 (rc3) now available
- From: nobody <nobody+lua-list@...>
- Date: Fri, 27 Jan 2017 01:16:09 +0100
On 2017-01-26 22:49, Egor Skriptunoff wrote:
> On Thu, Jan 26, 2017 at 5:50 AM, Charles Heywood wrote:
>> Is there a rawtype() planned to act as previous versions of type()
>> would?
> Instead of introducing new function "rawtype()", good old "type()"
> may return two values: raw type and "specialized" type:
>
> local t = setmetatable({}, {__name = "MyType"}) print(type({})) -->
> "table" print(type(t)) --> "table", "MyType"
>
> BTW, this way "math.type()" could be removed as it does not needed
> anymore:
>
> print(type(42)) --> "number", "integer" print(type(3.14)) -->
> "number", "float"
I like the idea, but it's possible that this causes a significant
slow-down for type-based branching. So let's do some measurements:
A quick & dirty test implementation (probably not optimal! and
incomplete): It just gets __name if available, doesn't call functions
like math.type and so on. (I wonder how that should work with e.g.
lpeg.type and other user additions. Yet another metamethod: __type? m))
*** lbaselib.c-orig 2017-01-27 00:33:07.854011135 +0100
--- lbaselib.c-type2 2017-01-27 00:32:46.670792561 +0100
*************** static int luaB_type (lua_State *L) {
*** 202,207 ****
--- 202,212 ----
int t = lua_type(L, 1);
luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
lua_pushstring(L, lua_typename(L, t));
+ int tt = luaL_getmetafield(L, 1, "__name");
+ if (tt == LUA_TSTRING)
+ return 2;
+ if (tt != LUA_TNIL)
+ lua_settop(L, -2);
return 1;
}
And a test script (doesn't do much besides calling type() in a loop):
-----
function typecase( v )
local t = type( v )
if t == "number" then return "n" end
if t == "string" then return "s" end
if t == "table" then return "t" end
if t == "nil" then return "x" end
return "?"
end
vals = { "foo", 23, true, io.stdin, nil, {}, setmetatable( {}, { __name
= false } ) }
local N = 2000000
for i = 1, 5 do
t0 = os.clock()
for i = 1, N do typecase( vals[math.random( 7 )] ) end
t1 = os.clock()
print( arg[-2], N, t1-t0 )
end
-----
Result:
./lua_orig 2000000 1.005907
./lua_orig 2000000 0.999243
./lua_orig 2000000 0.997433
./lua_orig 2000000 0.997195
./lua_orig 2000000 0.997136
./lua_type2 2000000 1.119795
./lua_type2 2000000 1.119341
./lua_type2 2000000 1.119024
./lua_type2 2000000 1.119046
./lua_type2 2000000 1.119908
So roughly 10% overhead for something that usually isn't used. Not too
bad, but not that nice either. (A more efficient version may be better
- if anyone wants to try. A more feature-complete version might also be
interesting.)
I like the general direction of the idea (there are more concepts of
"type" than just that of the seven primitive types), but it's not
something to quickly add, rather think some more about it first.
-- nobody