Перейти к содержимому
RccHD

Библиотека для работы с массивами байт в Lua

Рекомендуемые сообщения

Эта библиотека может пригодиться вам, если вы работаете с массивом байт, и при этом вам необходимо экономить оперативную память. В OpenComputers оперативной памяти иногда катастрофически не хватает, так как установлен лимит на 2МБ у компов и 4МБ у серверов
Примечание: эта библиотека использует библиотеку для создания классов. Скачать с pastebin
Эта библиотека очень проста и ОЧЕНЬ полезна, так как с помощью нее можно занимать до 20 раз меньше оперативки (по сравнению с table-массивами).
Массив байт создается таким образом:

local bytearray = require("bytearray")
local a = bytearray(20) -- 20 байт

bytearray легко записать в файл при необходимости:
 

file:write( bytearray.data )

У класса bytearray есть следующие методы:
write = function(pos, bytes) -- записывает байты bytes(table) начиная с позиции pos(number)
read = function(pos, count) -- считывает count(number) байт начиная с позиции pos(number)

clear = function() -- очищает массив байт ( заполняет нулями )

Вот пример работы:
SvRdePG.png

Может быть кому-нибудь кроме меня эта библиотека пригодится : )

Ответ на вопрос "почему просто не создать таблицу с числами?":
таблица с числами занимает больше памяти

Изменено пользователем RccHD

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хотите ужаснуться!?

Я протестил и сравнил, сколько на самом деле оперативной памяти можно сэкономить, используя эту библиотеку.

Вот, пожалуйста:

 

local bytearray = require("bytearray")
local computer = require("computer")

local freeMem = function() -- возвращает усредненное значение computer.freeMemory()
    local m = 0
    for i = 1, 20 do
        m = m + computer.freeMemory()
        os.sleep(0.2)
    end
    return m / 20
end


-- ТЕСТ 1 (bytearray)
local mem1 = freeMem()
local array = bytearray(100000) -- массив 100000 байт
array.write(3, {1, 2, 3, 4, 5, 6, 7, 8, 9})
local mem2 = freeMem()
print("Потрачено оперативки массивом байт(bytearray): "..tostring(mem1 - mem2))

print("\n\n\n")
-- ТЕСТ 2 (table)
local mem1 = freeMem()
local array = {}; for i = 1, 100000 do array[i] = 0 end -- массив 100000 байт
for i = 1, 9 do array[i + 3] = i end
local mem2 = freeMem()
print("Потрачено оперативки таблицой(table): "..tostring(mem1 - mem2))
И вот результат:

Y3TwuMA.png

Изменено пользователем RccHD

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Строки иммутабельны в луа, при изменении твоего массива уйдет уйма времени на копирование строк, сборщик мусора будет орать как лютый негр. Я тестил.

 

Пиковое потребление памяти при использовании строк было в несколько раз больше, чем при использовании массива.

К тому же, в луа числа 64-битные, поэтому для эффективного хранения нужно упаковывать байты по числам. Небольшой оверхед памяти при таком подходе будет куда менее критичным, чем иммутабельность строк.

 

Что за костыльная библиотека классов, которая не используя метатаблицы, создает копии всего класса на каждый инстанс пожирая память?

Изменено пользователем LeshaInc

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Строки иммутабельны в луа

Вот как раз поэтому они и занимают так мало оперативки

 

Пиковое потребление памяти при использовании строк было в несколько раз больше, чем при использовании массива.

Да, если записывать значения в bytearray по 100 раз в секунду, то сборщик мусора может и не справиться

 

Но если правильно использовать bytearray.write записывая сразу несколько байт, а не по одному, то можно сэкономить очень много оперативки

 

И да, я не позиционирую bytearray как замену table, так как они разные и нужны в разных ситуациях

Если нужно хранить МНОГО данных и не очень часто их обновлять, то однозначно нужно использовать bytearray

Изменено пользователем RccHD

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, если записывать значения в bytearray по 100 раз в секунду, то сборщик мусора может и не справиться

 

скажу больше, записываться может и по тысяче раз, а то и больше. для примера - получение данных с геосканера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Что за костыльная библиотека классов, которая не используя метатаблицы, создает копии всего класса на каждый инстанс пожирая память?

Может как-нибудь доработаю эту библиотеку

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

скажу больше, записываться может и по тысяче раз, а то и больше. для примера - получение данных с геосканера.

В таком случае, нужно записывать данные в bytearray порциями

Нужно сначала накопить порцию данных, а потом все разом записать

Пример:

 

local a = bytearray(100000)


local data = {} -- буфер
for i = 1, 1000 do
    os.sleep(1/1000)
    data[i] = getSomeDataFromGeoscan() -- скапливаем данные в буфере
end
a.write(2222, data) -- записываем данные в bytearray
data = nil -- очищаем буфер
Изменено пользователем RccHD

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

сборщик мусора будет орать как лютый негр. Я тестил.
 
Я попробую использовать bytearray вместо table в моей библиотеке двойной буфферизации и посмотрю, что получится.
Думаю, такие массивы байт могут быть незаменимы при умелом использовании

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

Что за костыльная библиотека классов, которая не используя метатаблицы, создает копии всего класса на каждый инстанс пожирая память?

Переписал библиотеку классов на метатаблицы, чтобы претензий не было :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

Может как-нибудь доработаю эту библиотеку
Предлагаю хранить байты не в строке, а в таблице чисел. По восемь байт на число (или сколько там?). При этом чтобы вставить/извлечь байт перелопачивать придется не всю длиннющую строку, а один number.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Предлагаю хранить байты не в строке, а в таблице чисел. По восемь байт на число (или сколько там?). При этом чтобы вставить/извлечь байт перелопачивать придется не всю длиннющую строку, а один number.

Очень хорошая идея, реализую сегодня(и наверное выложу на форум).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Лэша, про Нигера прям вообще загнал)) (с телефона не могу упомянуть)

По поводу либы - если прикрутишь туда методы работы с блочными дисками - будет хорошая основа для БД, давно бы пора СУБД на ОС)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...