È dovuto al ridimensionamento tabella ridimensionamento/rehash. Quando viene creata una tabella, è vuota. Quando si inserisce un elemento, viene eseguito un rehash e la dimensione della tabella viene aumentata a 1. Lo stesso accade quando si inserisce un altro elemento. La regola è che una tabella viene generata ogni volta che lo spazio non è sufficiente (in una matrice o in una parte hash) per contenere un altro elemento. La nuova dimensione è la più piccola potenza di 2 che può accogliere il numero richiesto di elementi. Per esempio. rehash si verifica quando si inserisce un elemento, se una tabella contiene 0, 1, 2, 4, 8, ecc. elemnts.
Ora la tecnica che si sta descrivendo consente di risparmiare quei rihashes, poiché Lua non riduce le tabelle. Quindi, quando si hanno frequenti operazioni di fill/flush table, è meglio (per quanto riguarda le prestazioni) farlo nel proprio esempio piuttosto che creare una tabella vuota.
Aggiornamento:
ho messo un po 'di test:
local function rehash1(el, loops)
local table = {}
for i = 1, loops do
for j = 1, el do
table[j] = j
end
for k in ipairs(table) do table[k] = nil end
end
end
local function rehash2(el, loops)
for i = 1, loops do
local table = {}
for j = 1, el do
table[j] = j
end
end
end
local function test(elements, loops)
local time = os.time();
rehash1(elements, loops);
local time1 = os.time();
rehash2(elements, loops);
local time2 = os.time();
print("Time nils: ", tostring(time1 - time), "\n");
print("Time empty: ", tostring(time2 - time1), "\n");
end
I risultati sono interessanti smettere. L'esecuzione di test(4, 10000000)
su Lua 5.1 ha dato 7 secondi per zero e 10 secondi per vuoti. Per le tabelle più grandi di 32 elementi, la versione vuota era più veloce (più grande è il tavolo, maggiore è la differenza). test(128, 400000)
ha dato 9 secondi per nils e 5 secondi per vuoti.
Ora su LuaJIT, dove le operazioni alloc e gc sono relativamente lente, l'esecuzione di test(1024, 1000000)
ha dato 3 secondi per i nils e 7 secondi per i vuoti.
P.S. Notare la differenza di prestazione tra Lua e LuaJIT. Per 1024 tabelle di elementi, Lua ha fatto 100.000 iterazioni di prova in circa 20 secondi, LuaJIT ha fatto 1.000.000 di iterazioni in 10 secondi!
Per ridurre le allocazioni di memoria - operazioni di deallocazione? –
Oltre ai problemi di prestazioni descritti nella risposta ... se la tabella viene utilizzata da altre parti del programma con altri nomi, il ciclo è assolutamente necessario. Se si esegue l'assegnazione, si perde semplicemente il collegamento all'oggetto tabella e gli altri nomi puntano ancora alla stessa tabella completa, mentre il ciclo lo cancella per tutti. –