Столкнулся с проблемой - скрипты "падают" из-за нехватки памяти. В одной из них формируется несколько сотен таблиц, в каждую из которых два раза в секунду добавляется новые элемент (история бид, оффер и сделок, подробнее см. ). Я пришел к выводу, что без удаления "старых" исторических значений из этих таблиц в течение сессии / одного запуска не обойтись. Однако, обнаружилось, что это очень затратная по ресурсам / времени процедура для которой я не вижу удобных альтернатив.
Стандартный подход - использовать table.remove. Однако, он дает возможность удалять только один элемент, при удалении первых элементов в массиве, многократно меняются индексы всех последующих элементов, что требует много времени. Так удаление первых 5 тысяч элементов таблицы с 10 тыс. полей заняло у меня 6,5 сек. - непозволительно долго.
Пример кода:
local ElemToKeep = 5000
tab1 = tabInit (1000000)
while #tab1 > ElemToKeep do
table.remove (tab1,1)
end
Есть обходные пути.
Можно использовать простое удаление элементов, например, так:
--local numElement = #tab2
--local toremove = numElement - ElemToKeep
--for k = 1, toremove, 1 do
--tab2[k] = nil
--end
Работа такого кода происходит гораздо быстрее (приблизительно в 2 тысячи раз в упомянутых условиях!). Однако, если мы удалим элементы в начале таблицы, например, с 1 по 2000, мы не сможем использовать их перебор через ipairs, и хуже того, мы не сможем оперативно посчитать число элементов в таблице с использованием #. Их число можно будет получить только путем перебора с вставкой счетчика в цикл pairs.
Можно изголяться дальше в этом направлении. Например, каждый раз вставлять новые элементы в таблицу с использованием table.insert и присваивать им индекс 1, сдвигая все остальные в конец. Это решит проблему с ipairs, # и подсчетом элементов - достаточно будет обрезать "хвост" массива/таблицы, индексы будут начинаться с единицы и будут идти без пробелов. Однако, такой подход означает, что мы все равно выполняем ресурсозатратную процедуру (переименование индексов) -- с меньшей потерей времени, но чаще (при каждом добавлении нового элемента).
Есть ли у кого-то пример эффективного решения подобной проблемы?
Стандартный подход - использовать table.remove. Однако, он дает возможность удалять только один элемент, при удалении первых элементов в массиве, многократно меняются индексы всех последующих элементов, что требует много времени. Так удаление первых 5 тысяч элементов таблицы с 10 тыс. полей заняло у меня 6,5 сек. - непозволительно долго.
Пример кода:
local ElemToKeep = 5000
tab1 = tabInit (1000000)
while #tab1 > ElemToKeep do
table.remove (tab1,1)
end
Есть обходные пути.
Можно использовать простое удаление элементов, например, так:
--local numElement = #tab2
--local toremove = numElement - ElemToKeep
--for k = 1, toremove, 1 do
--tab2[k] = nil
--end
Работа такого кода происходит гораздо быстрее (приблизительно в 2 тысячи раз в упомянутых условиях!). Однако, если мы удалим элементы в начале таблицы, например, с 1 по 2000, мы не сможем использовать их перебор через ipairs, и хуже того, мы не сможем оперативно посчитать число элементов в таблице с использованием #. Их число можно будет получить только путем перебора с вставкой счетчика в цикл pairs.
Можно изголяться дальше в этом направлении. Например, каждый раз вставлять новые элементы в таблицу с использованием table.insert и присваивать им индекс 1, сдвигая все остальные в конец. Это решит проблему с ipairs, # и подсчетом элементов - достаточно будет обрезать "хвост" массива/таблицы, индексы будут начинаться с единицы и будут идти без пробелов. Однако, такой подход означает, что мы все равно выполняем ресурсозатратную процедуру (переименование индексов) -- с меньшей потерей времени, но чаще (при каждом добавлении нового элемента).
Есть ли у кого-то пример эффективного решения подобной проблемы?