RccHD 136 Опубликовано: 18 сентября, 2017 (изменено) Совсем недавно я выложил свою библиотеку, которая позволяет экономить оперативную память при хранении бинарных данных.Из фатальных недостатков той старой библиотеки можно выделить:1) Колоссальная нагрузка на CPU и сборщик мусора2) Работа со иммутабельными строкамиПолучив порцию критики, я переписал библиотеку и добился офигенных результатов.Новая библиотека экономит ровно столько же оперативки ( экономия до 80-90% ) и при этом не имеет перечисленных недостатков старой. UniDataArray.lua Примечание: для работы с этой библиотекой необходимо наличие следующий библиотек:1) num_transform.lua2) class.lua (доработанная версия)Новая библиотека сильно отличается от старой версии. Теперь вместо строк используется таблица с числами. Интерфейс взаимодействия с UniDataArray реализован так, что при каждой операции записи-чтения данных происходит изменение внутреннего содержимого таблицы с числами.В Lua используются 64-битные числа, что дает возможность использовать их как хранилище более мелких "частичек информации". Например, одно число в Lua может хранить информацию о 8 байтах или о 64 битах.Работа библиотеки основана как раз на этой возможности умещать данные в больших числах.Вот пример использования библиотеки UniDataArray.lua -- ФУНКЦИЯ КРАСИВОЙ ОТРИСОВКИ -- К библиотеке отношения не имеет local pprint = function(v, t) print("\27[32m"..tostring(v or "").."\27[37m") io.write("-> ") if type(t) == "table" then for k, v in pairs(t) do io.write(tostring(v).." ") end else io.write(tostring(t)) end print("\n------------------------------------") end local UniDataArray = require("UniDataArray") -- создание массива размером 20 с разрядностью = 256. (массив байт) -- т.е. 20 байтlocal array = UniDataArray(20, 256) -- числа... local numbers = {1,0,234,22,12,99,44,3,121,200} -- позиция курсора local position = 0 -- запись чисел numbers в массив array начиная с позиции position position = array.write(position, numbers) --- ВЫВОД ИНФОРМАЦИИ НА ЭКРАН : ----------------------------------------- print("\n\n")---------------------------- ----------------------------------------- pprint("Кусок из 5 байт (с 2 по 6)" ,array.read(1, 5) ) pprint("Исходные данные (каждое число -- это отдельный блок) " ,array.data ) pprint("Количество блоков" ,array.length ) pprint("Размер блока " ,array.block_len ) pprint("Общее кол-во отдельных элементов" ,array.block_len * array.length ) pprint("Позиция курсора" ,position ) pprint("Первый блок " ,array.internal.getBlock(1) ) pprint("Второй блок " ,array.internal.getBlock(2) ) ----------------------------------------- print("\n\n")---------------------------- ----------------------------------------- Вот такой текст мы увидим на экране:Мы видим, что первое число в "исходных данных" равняется 1103438941283Это число имеет такое большое значение, потому что оно хранит байты {1, 1, 234, 22, 12, 99} (см. "Первый блок")Каждое число в "исходных данных" является блоком, в котором хранятся числа в определенной системе счисления ( в данном случае система счисления = 256 )Все аналогично и для второго блока, для третьего и так далее... Абзац с неинтересным описанием некоторых интересных моментов:При создании массива данных в кодировке base размера N программа создаст ровно столько блоков, сколько необходимо для хранения N чисел.Чем больше значение кодировки, тем меньше чисел этой кодировки может поместиться в блок.При создании массива байт каждый блок будет вмещать 6-7 ячеек. local arr = UniDataArray(100000, 256) -- кодировка 256, значит это байты print(arr.block_len) -- длина блока = 6 ячеек print(arr.length) -- всего создано 16667 блоков Но вот при создании массива бит, каждый блок будет иметь аж 62 ячейки: local arr = UniDataArray(100000, 2) -- кодировка 2, значит это биты print(arr.block_len) -- длина блока равна 62 ячейкам print(arr.length) -- всего создано 1613 блоков Также есть возможность создания массивов в кодировках 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, но кому оно надо, я не знаю Реализовал "чтобы было". Лично я пользуюсь только кодировками 2 и 256.Каждый блок занимает примерно 64 бита вне зависимости от количества ячеек в нем Краткая документация библиотеки Чтобы создать UniData-массив нужно вызвать функцию-конструктор передав в нее два аргумента:1) необходимое количество ячееки2)допустимую кодировку этих ячеек. Пример: local UniDataArray = require("UniDataArray") local array = UniDataArray(100000, 4) -- создание массива из 100000 'четырехразрядных' чисел У класса UniDataArray есть следующие методы:write = function(pos, bytes) -- записывает числа bytes(table) начиная с позиции pos(number). Возвращает позицию последней записанной ячейкиread = function(pos, count) -- считывает count(number) чисел начиная с позиции pos(number). Возвращает позицию последней прочитанной ячейкиfill = function(elem) -- устанавливает значение elem(number) всем ячейкам в массиве Пример использования UniDataArray как массива битов Ну, в этом нет ничего сложного: local UniDataArray = require("UniDataArray") local array = UniDataArray(20, 2) -- массив из 20 битов array.write(0, {0, 1, 0, 1, 1, 1, 0}) -- записать биты 0101110 в ячейки после нулевой. 0 array.write(5, {1, 1, 1, 1, 0, 1, 1}) -- записать биты 1111011 в ячейки после пятой. 5 local someData = array.read(2, 5) -- прочитать 5 битов начиная с позиции 2 print(table.unpack( someData )) -- выведет на экран 01111 Ну и на сладкое у нас тест производительности!Table VS UniDataArray Запускал на тех же тестах, что и в прошлый раз. local bytearray = require("UniDataArray") 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 (UniDataArray) local mem1 = freeMem() local array = UniDataArray(100000, 256) -- массив 100000 байт array.write(3, {1, 2, 3, 4, 5, 6, 7, 8, 9}) local mem2 = freeMem() print("Потрачено оперативки массивом байт(UniDataArray): "..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)) Результат теста:Плюсы библиотеки: описаны выше( потребление оперативки сокращается в 20, мать его, раз! )Минусы: библиотека пока еще очень сырая, но это поправимо. Я ее еще успею отполировать Изменено 19 сентября, 2017 пользователем RccHD 4 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RccHD Автор темы 136 Опубликовано: 18 сентября, 2017 Я писал эту чертову программу весь день, но зато узнал много нового Я уверен, применений у этой библиотеки огромное количество, так как в опенкомпах всегда не хватает оперативки(в сложных графонистых системах). Никто ведь не будет отказываться от 20-кратного уменьшения потребления оперативной памяти игрушечного компа Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 904 Опубликовано: 18 сентября, 2017 Интересно, работает ли либа на Lua 5.2? Возможный диапазон целых чисел на прошлой версии отличается от 5.3: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RccHD Автор темы 136 Опубликовано: 18 сентября, 2017 (изменено) Интересно, работает ли либа на Lua 5.2? Возможный диапазон целых чисел на прошлой версии отличается от 5.3: Если что-то перестанет работать, изменю в коде либы число '64' на '32' или добавлю проверку на версию Lua Изменено 18 сентября, 2017 пользователем RccHD Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RccHD Автор темы 136 Опубликовано: 19 сентября, 2017 Черт, я кажется скинул забаглванную версию. При работе с шестнадцатиричными числами происходит какая-то неведомая магия. Сейчас буду править код Пока не спешите использовать эту либу в каком-то серьезном проекте. Эта либа будет считаться 'проверенной' после того, как часть операционки я напишу на UniDataArray. Пока что нестабильно работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
RccHD Автор темы 136 Опубликовано: 20 сентября, 2017 Все пофиксил и потестил. Работает стабильно ( вроде бы ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Jakowlew 11 Опубликовано: 9 марта, 2018 Объясните дураку, как скачать библиотеку? Я потратил 15 минут и не нашел в четырежды просмотренном посте ссылку на саму либу, только на зависимости. И такое почти во всех темах с библиотеками. ГДЕ ОНИ ХРАНЯТСЯ? ОТКУДА ИХ КАЧАТЬ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Fingercomp 4 409 Опубликовано: 9 марта, 2018 Объясните дураку, как скачать библиотеку? Я потратил 15 минут и не нашел в четырежды просмотренном посте ссылку на саму либу, только на зависимости. И такое почти во всех темах с библиотеками. ГДЕ ОНИ ХРАНЯТСЯ? ОТКУДА ИХ КАЧАТЬ? А это кто-то из админов доигрался с шаблонами. Так, что теперь они все потёрлись. А в них была инфа, включая ссылку на либу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Alex 4 683 Опубликовано: 10 марта, 2018 @@Fingercomp а что за библиотеки? какие шаблоны? что именно потерлось? у кого? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Fingercomp 4 409 Опубликовано: 10 марта, 2018 (изменено) В начале поста был список с инфой всякой про библиотеку. Название: бла-бла Версия: 1.4.2 Скачать: ссылка ...и так далее. Вот такая штука. Значения для них ставились в специальных полях, отдельно от самого сообщения. И темы по шаблону создавались тоже: сначала инфа, потом само сообщение. А сейчас всё это внезапно исчезло, так как шаблон удалён был. Я полагаю, Кибер знать больше должен здесь. Изменено 10 марта, 2018 пользователем Fingercomp Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
vford 12 Опубликовано: 8 февраля, 2021 Прошу прощения, что занимаюсь некропостингом. Уж не знаю, пригодится ли эта библиотека кому-нибудь, но ссылку на нее я нашел. Можете переходить, смотреть. Pastebin: UniDataArray 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах