I understand why str:len() is faster than str.len(str). What I don’t understand is why str:len() is faster than string.len(str).
On Aug 7, 2014, at 9:39 AM, Thiago L. <fakedme@gmail.com> wrote:
2 [2] GETTABUP 0 0 -4 ; _ENV "string"
3 [2] GETTABLE 0 0 -5 ; "len"
4 [2] GETTABUP 1 0 -1 ; _ENV "str"
5 [2] CALL 0 2 2
6 [2] SETTABUP 0 -3 0 ; _ENV "x"
7 [3] GETTABUP 0 0 -1 ; _ENV "str"
8 [3] SELF 0 0 -5 ; "len"
9 [3] CALL 0 2 2
10 [3] SETTABUP 0 -6 0 ; _ENV "y"
11 [3] RETURN 0 1
Above is the Lua 5.2 bytecode for:
x = string.len(str)
y = str:len()
Note that string.len(str) takes 3 instructions (2-4) to prepare for the len() call, all of which are table lookups with string keys. str:len() only has two instructions (7-8) to prepare for the len() call. Since Lua is an interpreter, you are already winning in the second case since the bytecode threading overhead is lower (2 instead of 3 instructions). Note that this overhead is less trivial than it might appear on many processors since this kind of threading can often stall the CPU pipeline (and, incidentally, is one of the reasons “fatter” bytecode designs are often faster).
Now, the SELF opcode does have a little more internal overhead, since it has to locate the metatable for “str” before it can lookup the “len” method, but this is trivial compared to a full table lookup, as the metatable is directly accessible.
—Tim