B
B
bulatzaripov2014-08-04 14:22:17
Arrays
bulatzaripov, 2014-08-04 14:22:17

When exactly in Lua does an array (a table with only array-part ) acquire a hash-part (become a hash )?

It is necessary to transfer tables (tables) in Lua code over the network (computer multiplayer game).
In this connection, the question of the size of the transmitted data (about keeping them as small as possible) is very relevant.
To save the structure of the table and "hold" it in an array-like style, it is recommended to use table.insert, table.remove...
There is a code:

local var = {}

for i = 1, 10000, 1 do
    table.insert ( var, i )
end

var[10000] = { var = 1, some = "string", another = {} }
var[555] = false
var[1] = 1
var[2] = {}

var[1] = {}

Questions:
1) Will the var table remain an array (a table with an array part only), or is it converted to a hash (a table with two parts array and a hash ). (I myself think the answer "will remain only with array-part", since the structure of the table is not affected - only the values ​​\u200b\u200bof the elements are affected, but I really doubt this answer, but you need to know for sure).
2) Why? :) How to check it?
3) Ultimately specifying: if the table initially has only an array-part, then will changing the value of the table element directly through the syntax var[1] = {} var[2] = false var[3] = 1, etc. to change the structure of the table and the appearance of a hash-part in it? (Provided that it is given in advance: )
local var = {}
for i = 1, 10000, 1 do
    table.insert ( var, i )
end

I suspect the answer for the code above is "no", but:
var[10001] = 1
Will already affect the table structure and create memory overhead.
In this connection, I think the answer is as follows (for the code above): up to n <= 10000, the var[n] = {} code does not affect the structure of the table, which means it does not lead to the creation of a hash-part (the table remains array-like). However, the code var[n + 1] = {} will result in a memory overhead (read more here www.lua.org/gems/sample.pdf ) Is the
answer correct or not?
Thank you!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
Boris Nagaev, 2015-03-27
@starius

The ltable.c file says the following:
Thus, the array spans keys from 0 to such a number n that at least half is used. Let's take another look at the code for the computesizes function , which decides what the size of the array will be when the table is resized. This function iterates over powers of two (1, 2, 4, 8...) and sees how much of the array would be occupied if it were that size. Stops when this proportion becomes less than half. It is easy to prove that with such an array size selection algorithm and with continuous filling of all keys from 1 to n, the array size greater than or equal to n will be chosen.
By the way, it also follows from this that when adding elements to the end of the array, there will be overhead, but not for the hash part, but for empty array elements allocated "in reserve". But it should be so, so as not to rebuild the array with each new element. (In C++, vector.push_back behaves the same way.) If you already know the final size of the array and want to profit from it, write a C extension that calls lua_createtable(L, array-size, 0).
Regarding whether the hash part will appear when replacing values ​​with different types. Will not appear. The fact is that in a key-value pair, the key and values ​​are stored in different fields. I tracked how the i_val field is used, it turned out only in the gval macro, the type of which does not appear anywhere (only checks for nil).
Also, I would recommend using rawset and lua_rawseti as they don't check metamethods and should therefore be faster. About lua_rawseti, I'm sure that it works faster, but I suspect about rawset.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question