[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: 51w6 *s performance patch
- From: Mike Pall <mikelu-0505@...>
- Date: Thu, 19 May 2005 19:10:14 +0200
Hi,
not to detract anyone from the current syntactic flamewar,
but there's another problem with *s (where s is a string):
$ TIMEFORMAT="%U"
$ time lua51w6 -e 'local s=""; for i=1,1e7 do local x = *s end'
3.089
$ time lua51w6 -e 'local s=""; for i=1,1e7 do local x = s:len() end'
3.434
$ time lua51w6 -e 'local s,f="",string.len; for i=1,1e7 do local x = f(s) end'
2.594
[Lower numbers are better]
Well, looks like string.len is faster (!) than *s. This is
because the current implementation needs to go through the
string metatable every time. Patch attached below.
Look at the improvement:
$ time lua51w6-slen -e 'local s=""; for i=1,1e7 do local x = *s end'
0.793
[
The semantic difference is that you cannot swap string.* and
expect *s to get a new meaning for plain strings. But the only
reason you'd want to do that would be for UTF-8. And there
every string has both a 'length' and a 'size'. Since this is
a matter of definition only, you ought to use s:len() consistently
when you want the length in characters and use *s when you want
the storage size.
]
Oh and another thing: did anyone notice that *t is _NOT_
overridable for plain tables? That makes it much less useful.
You cannot construct your own types with plain tables and
give *t any other meaning (you can do so with userdata).
Alas, the performance of *t for large tables isn't stellar
(it needs to do a binary search). So making it check the
metatable everytime would slow it down even more ...
So, returning you to the syntactic flamewar: I want to
voice my opinion that ...
t[*t+1] = x
... looks really, really ugly for an append operation.
Read the old thread for a bunch of suggestions. I'd rather
have an append operator (t[] = x) than a size/length operator.
The former is much more useful in a high-level language since
'size' is a low-level property of objects and should be
encapsulated by high-level methods (e.g. iterators).
Bye,
Mike
--- lua-5.1-work6/src/lvm.c
+++ lua-5.1-work6-slen/src/lvm.c
@@ -549,6 +549,9 @@
if (ttype(rb) == LUA_TTABLE) {
setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
}
+ else if (ttype(rb) == LUA_TSTRING) {
+ setnvalue(ra, cast(lua_Number, tsvalue(rb)->len));
+ }
else { /* try metamethod */
Protect(
if (!call_binTM(L, rb, &luaO_nilobject, ra, TM_SIZ))