Edgar Toernig wrote (in the thread 'Lua 5 and tags'):
Jamie Webb wrote:
I'd like to add that adding an array part to userdatas would also
provide fast typing:
Hmm... that gets me back to the old idea of merging userdata and
tables: give every table an additional void* field and remove the
userdata type completely *g*
Maybe it's time to start a 'Userdata/Table Unification' thread ...
The same topic pops up every so often. Summing up all advantages and
disadvantages in one thread may be helpful. And it may be a first step
in convincing the authors of Lua to add this to the core.
Just a few thoughts to start the discussion:
- Adding a void* to the table structure incurs no additional memory
overhead on most systems. I.e. the userdata pointer is free!
The current table structure is 32 bytes long (on 32 bit systems) and
anything between 29 and 36 bytes leads to the same effective memory
allocation due to malloc overhead and alignment constraints. YMMV.
- A plain userdata object has 16 bytes (on 32 bit systems) plus the
userdata itself plus any malloc and alignment overhead.
The savings provided by a trivial userdata object over a unified
userdata/table object are negligible. If you really need to save
space
there is still lightuserdata (I think this type is valuable and
should
not be affected by the unification).
More complex libraries actually need less memory because they no
longer
need table wrappers, auxiliary tables or per-object metatables.
- I cannot see any noticeable speed difference between the current
approach
and the unified approach (method access, userdata pointer access,
type
checking ...).
- Current userdata objects are allocated by the Lua core and cannot be
resized nor moved nor shared. Quite a few libraries end up storing
a single void* in a userdata object. This is wasteful.
Leaving the allocation management to the C library seems to be the
better
solution in the long term IMHO.
- Many libraries need to store additional Lua objects along with
userdata
values and end up abusing the metatable or weak tables. This
complicates
type checking and/or garbage collection.
- Tables do not have a __gc() metamethod. This prevents wrapping
userdata
objects into a table because __gc() metamethods often need to have
a look at the full object context and not just at individual userdata
objects. Unifying userdata and tables would provide such a __gc()
metamethod for tables. This is advantageous even for pure Lua code.
- Current userdata objects cannot be subclassed easily. Unless you have
the cooperation of the C library you need to wrap them up in a table
and
store any subclass fields there. But this approach is troublesome
due to the lack of a __gc() metamethod for tables. See above.
Subclassing gets trivial with a unified userdata/table object.
- Every unified table object has a void*. This may be useful for many
more
scopes than just plain library objects (e.g. module namespace
tables).
- I have not taken a closer look at the issues that the unification
rises
for the Lua garbage collector. I may be wrong, but I think it gets
simpler
because the tricky handling for userdata objects can be dropped.
- Reducing diversity usually simplifies the implementation and this
leads
to fewer bugs. Some people believe this is the only measure that
counts.
Bye,
Mike