PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » Многомерные массивы переменной размерности


Многомерные массивы переменной размерности

Сообщений 1 страница 25 из 25

1

Всем привет.

Необходимо реализовать хранение данных в 2х- и 3х-мерных массивах. Но нюанс заключается в том, что количество элементов на каждом уровне должно быть разным. Насколько я понимаю, при использовании Dim a.l(10, 20, 30) будет создан 3х-мерный массив фиксированного размера по всем трем уровням, т.е. на первом - 10 элементов, на каждом втором - по 20, на каждом из них - по 30.

Логика работы такова, что на этапах обхода вычисляется размер той или иной ветки на том или ином уровне - это раз, и два - нет смысла хранить данные в массиве вида a.l(50, 1000), если по факту там от силы пара веток с 1000 элементов на втором уровне, а все остальные по парочке значений содержат.

И чтобы совсем здорово было - таких массива 3 и их числовые ключи используются для сквозной перелинковки друг с другом (читай - по номеру ключа в одном массиве можно получить относящиеся к этим данным - данные из второго массива и т.д.)

Просто сижу переписываю один весьма занятный проект с PHP

0

2

массив 10, 20, 30 представляет собой куб размером 10х20х30. Размерность поменять нельзя, если это куб, то куб, можно поменять только размеры куба. При этом как я понимаю можно вычислять заполненность каждого размера, для размера 20 их будет 10х30=300, для 10 их будет 600, для 30 их будет 200 итого 1100 итераций надо сделать чтобы проверить заполненность всех, но опять же что если некоторые поля пусты, является ли 0 ограничителем заполненности? если 0 позволителен, то он не является определителем заполненности.

0

3

0 может существовать и быть валидным значением, т.к. массив даблов.

0

4

В PB, как и Си,Асм, ... , массивы это кусок памяти конкретных размеров вычисляемых на основе размера элементов и их количества.
И доступ к элементам таким же образом вычисляется.
Переменных размеров не бывает.
Для переменного многообразия организуются другие структуры, типа списки, деревья и прочее и иногда в динамических языках именно они тоже называются "массивами".
Для работы с такими данными есть много инструментов, некоторые живут по пол века и больше.
Например http://www.minimdb.com/
Там есть бесплатный minimono. это фактически аналог sqlite dll, но для работы с "деревьями" и без SQL
И самое удивительное то, что есть примеры для PB.

p.s. http://www.minimdb.com/doc.html

Отредактировано useful (25.08.2023 15:13:33)

0

5

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

0

6

UnDetected написал(а):

но во-первых это сторонние костыли

Кому не нравятся сторонние костыли, пишет свои.

UnDetected написал(а):

крутить массивы в памяти нужно сильно часто и быстро

Если про minimono, то в основе полувековая тренировка КРУТИТЬ :D
https://ru.wikipedia.org/wiki/MUMPS

Отредактировано useful (25.08.2023 15:38:45)

0

7

UnDetected написал(а):

Необходимо реализовать хранение данных в 2х- и 3х-мерных массивах.

Но если речь о таком количестве и памяти хватает, то кто мешает пометить не используемые элементы какой нибудь константой типа -1 и сделать вид, что их не существует, а например в 0-х элементах хранить количество реальных в конкретном измерении.

MUMPS(minimono) это для того случая, когда данных в разрежённом массиве (именно так называется этот случай) заведомо больше, чем доступной памяти.
И технология манипуляции активными страницами виртуальной памяти специально для этого организуемой отработана досконально.
Т.е. часто используемые узлы дерева(элементы массива) всегда в памяти насколько её хватает а редко используемые на диске и чтение запись в случае изменений скрыта реализацией, о ней нет нужды заботиться.
Если начать заботиться, то вероятность сделать что то более быстрое, чем то над чем куча народу десятки лет работала точно мала.

Отредактировано useful (25.08.2023 15:59:51)

0

8

Не понятно в чём загвоздка? Можно контролировать размеры заполненности по выделенным для этого переменных и записывать их туда в процессе заполнения.

0

9

https://intellect.icu/razrezhennye-mass … ka-si-4503

0

10

UnDetected написал(а):

Необходимо реализовать хранение данных в 2х- и 3х-мерных массивах. Но нюанс заключается в том, что количество элементов на каждом уровне должно быть разным.

В структурах могут быть массивы и их размер можно задать для каждого элемента в отдельности.

Код:
Structure sM3
  Array m3.i(0)
EndStructure

Structure sM2
  Array m2.sM3(0)
EndStructure

Dim m1.sM2(10)

ReDim m1(0)\m2(100)
ReDim m1(0)\m2(10)\m3(10)

ReDim m1(1)\m2(4)
ReDim m1(1)\m2(0)\m3(1000)

Debug ArraySize(m1())
Debug ArraySize(m1(0)\m2())
Debug ArraySize(m1(0)\m2(0)\m3())
Debug ArraySize(m1(0)\m2(10)\m3())
Debug ArraySize(m1(1)\m2())
Debug ArraySize(m1(1)\m2(0)\m3())

0

11

Пётр
Интересно сравнить скорость доступа в таком массиве, чтобы получить элемент надо перейти на указатель, прочитать там следующий указатель, перейти к нему и там прочитать указатель или данные, но это цепочка переходов по 2-м указателям к третьему. А в стандартном массиве он не может иметь разное число элементов на одной размерности, но доступ скорее всего является произведением индексов.

0

12

А меня попутно возник вопрос по этой mimim.
Собственно, надо что-то типа такого, небольшое, простое, но быстрое. Главное - без сервера. С возможностью доступа из нескольких процессов одновременно.
Всякие sqlite сильно избыточны да и по скорости, имхо, желают лучшего.
Цель - использовать для портабелизации программ как замену реестра.

0

13

Пётр написал(а):

UnDetected написал(а): В структурах могут быть массивы и их размер можно задать для каждого элемента в отдельности.

Глянем.

Smitis написал(а):

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

Да ну? Отрубаешь журнал через PRAGMA, оптимизируешь там же размер, используешь транзакции в конце концов - и получаешь запись в несколько десятков тысяч строк в секунду и оперативный поиск. Интересно даже, что за прога такая должна быть, чтобы ТАК "любить" реестр.

Ну а если и этого мало, то никто не мешает создавать базу в памяти через :memory: и линковать ее в БД на диске. Пока работаешь с прогой - гоняешь все в памяти, а перед завершением работы тупо дампишь БД из памяти в прилинкованную на диск. Так что зря вы на sqlite наговариваете - весьма скоростная БД в умелых руках =)

Вот макрос из одного проекта как есть:

Код:
Macro _fastdb
	sqlite::put("PRAGMA synchronous = OFF")    	;	OFF | NORMAL | FULL
	sqlite::put("PRAGMA temp_store = MEMORY")    ;	DEFAULT | FILE | MEMORY
	sqlite::put("PRAGMA journal_mode = MEMORY")    ;	DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
	sqlite::put("PRAGMA page_size = 4096")
	sqlite::put("PRAGMA cache_size = 16384")
EndMacro

Отредактировано UnDetected (25.08.2023 19:24:32)

0

14

UnDetected

UnDetected написал(а):

Интересно даже, что за прога такая должна быть, чтобы ТАК "любить" реестр.

Я же говорю - портабелизация программ. Не какой-то одной отдельной, а в целом. https://forum.ru-board.com/topic.cgi?fo … art=340#lt
Проблема примерно та же, что и топикстартера - динамические массивы.
Сейчас всё хранится в памяти, размер массивов меняется через Redim, для большинства программ это никак не заметно.
Но расшарить массивы PureBasic между несколькими процессами не получается. Вот и ищу обходной путь.

0

15

UnDetected написал(а):

Вот макрос из одного проекта как есть:

Хмм... Плохо я знаю sqlite, да.

0

16

Smitis
Если прога работает сама с реестром то как ты перехватываешь запись/чтение в реестр? Можно использовать XML, JSON, они сохраняют структуры/массивы без заморочек в файл. Можно монтировать куст реестра, юзать его на момент запущенной проги, потом выгружать.

0

17

Во всех подобных темах меня не покидает ощущение, что проблема не в том, что в том или ином языке чего то не хватает, а в том, что проблема в техническом дизайне.
Все пишут о том, что не могут найти решения описывая свои попытки, но не пишут о сути стоящей задачи.
Уверен на 99%, что двое из участников этой ветки на самом деле не имеют проблем совсем. Проблемы в том как они пытаются решить задачу.
Прикладную проблему опишите. И станет понятно а нужны ли вам разрежённые массивы или расшаренные массивы.
Может и не нужны вовсе?

Отредактировано useful (25.08.2023 20:17:48)

0

18

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

Можно переписать все с нуля, взяв только требуемый алгоритм работы - но это уже разработка с нуля, а не задачка по конвертации кода на пару часов. Вот и все дела)))

0

19

AZJIO

AZJIO написал(а):

Если прога работает сама с реестром то как ты перехватываешь запись/чтение в реестр?

MinHook

AZJIO написал(а):

Можно монтировать куст реестра, юзать его на момент запущенной проги, потом выгружать.

Да, работает, но там проблема с доступом проблема.

useful написал(а):

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

Без обид, но это высказывание в стиле небезызвестного "капитана очевидность".

0

20

Smitis
Я в AutoIt3 написал функционал выбора пользователя где хранить данные ini или реестр, но там ini-подобная структура, в реестр везде строки, аналог ini-файла, то есть во всех случаях с данными обращаешься как со строками. Но как я понимаю это не подходит. Если только не задать тип данных в ini, например в AkelPad автор бинарные данные записывает как есть бинарно. То есть надо делать типы данных как в реестре, делать приставку к параметрам, типа num.DWORD=1234 и конвертировать это как число, data.BIN=0F67DE и т.д. А в секции/группы указать полный путь [HKEY_CURRENT_USER\Software\Test]

0

21

Smitis написал(а):

Без обид, но это высказывание в стиле небезызвестного "капитана очевидность".

Так это и есть очевидность.
Т.е. я уверен, что не существует не решаемой задачи совместного использования данных.

Вот этого в природе не существует!!! Очевидно же!!!
"Но расшарить массивы PureBasic между несколькими процессами не получается. Вот и ищу обходной путь."

P.s. Помимо https://ru.wikipedia.org/wiki/Разделяемая_память

Для диалога, если обходной путь всё таки нужен, важно не абстрактное "массивы PureBasic", а описание задачи:

какие данные, в каком объёме, кем создаваемые и насколько часто модифицируемые, с какой целью требуется совместно использовать какому количеству процессов, кем и с какой интенсивностью порождаемых.

Создаём отдельную ветку и очевидно же на 111% находим решение.

Отредактировано useful (26.08.2023 12:59:43)

0

22

AZJIO

AZJIO написал(а):

То есть надо делать типы данных как в реестре, делать приставку к параметрам, типа num.DWORD=1234 и конвертировать это как число, data.BIN=0F67DE и т.д. А в секции/группы указать полный путь [HKEY_CURRENT_USER\Software\Test]

Это не проблема. С хранением проблем нет. Всё хранится в файле в текстовом виде, бинарные данные в hex, все реестровские типы данных поддерживаются.

0

23

useful

useful написал(а):

Для диалога, если обходной путь всё таки нужен, важно не абстрактное "массивы PureBasic", а описание задачи:

какие данные, в каком объёме, кем создаваемые и насколько часто модифицируемые, с какой целью требуется совместно использовать какому количеству процессов, кем и с какой интенсивностью порождаемых.

Сложный вопрос. Программы то разные. Одни много пишут в реестр, другие почти ничего.

В настоящий момент настройки из реестра хранятся в текстовом файле с определённой структурой записей (правда, встречаются специальные служебные символы и некоторые очень "умные" текстовые редакторы испытывают когнитивный диссонанс).
При старте программы файл читается и в памяти создаются два динамических массива (точнее, массивы обычные, размер меняется через Redim.) - один для хранения путей из реестра, к которым обращается программа и на основе которого потом формируются виртуальные хендлы для функций работы с реестром. Второй массив - непосредственно хранимые в реестре данные.
При завершении программы всё пишется обратно.
Отлично работает для одного процесса. Собственно, попадалась только одна программа (сейчас, к сожалению, сходу не скажу какая), которая создавала ОЧЕНЬ много разделов в реестре (десятки тысяч) и всё это начинало тормозить.

Создал тему PurePortable - портабелизация программ

Отредактировано Smitis (26.08.2023 15:43:01)

0

24

Useful с minimino наверное прав,(если как понял речь о виртуальной памяти),дело в том что там адрес ссылка остаётся постоянной от начала и до конца выделенной памяти,иначе если даже на все писать то память по адресам кускам памяти может поменять значение при расширении на более доступный размер а смена адресов от начала адреса до конечного это тоже издержки доп алгоритм.
Ps:Начинал я писать алгоритмы на искусственную жизнь при её развитии и само роста при жизни со сменой молекулярной структуры в процессе развития .но сложно в одиночку и затратно по времени.

0

25

UnDetected написал(а):

Всем привет.

Необходимо реализовать хранение данных в 2х- и 3х-мерных массивах. Но нюанс заключается в том, что количество элементов на каждом уровне должно быть разным. Насколько я понимаю, при использовании Dim a.l(10, 20, 30) будет создан 3х-мерный массив фиксированного размера по всем трем уровням, т.е. на первом - 10 элементов, на каждом втором - по 20, на каждом из них - по 30.

Логика работы такова, что на этапах обхода вычисляется размер той или иной ветки на том или ином уровне - это раз, и два - нет смысла хранить данные в массиве вида a.l(50, 1000), если по факту там от силы пара веток с 1000 элементов на втором уровне, а все остальные по парочке значений содержат.

И чтобы совсем здорово было - таких массива 3 и их числовые ключи используются для сквозной перелинковки друг с другом (читай - по номеру ключа в одном массиве можно получить относящиеся к этим данным - данные из второго массива и т.д.)

Просто сижу переписываю один весьма занятный проект с PHP

Не существует классических массивов, таких как вы описали. Тут, на форуме это уже сказано. То, что вы описали, уже не массив, а другая организация данных. В PHP, на сколько я помню, массивы по большей части ассоциативны, но похожие на многие структуры, по сути, там ключ и значение. Вам нужно продумать и создать, свою организацию данных. Но, вы хотите быстро... - Качественно, это не получится!

Если проект действительно стоящий и вам интересно его делать, то запаситесь терпением. Делайте, и спрашивайте на форме, подскажем, что можем.
Если не критична скорость добавления, а необходима скорость поиска, то смотрите в сторону сбалансированных деревьев, АВЛ, Красно-Чёрное и т.п. СУБД, используют эти алгоритмы, но за счёт парсинга строк и дополнительных накруток, которые вам могут не понадобиться, время поиска может увеличиться. В отличии, от того, если бы вы организовали правильную структуру непосредситвенно в PB.
И конечно же, это касается больших данных. Если у вас данных не так много, то не заморачивайтесь, делайте обычными массивами, ничего страшного не случится. Более приближенно к PHP, использовать хэш-карту.

Если же вы, всё же скрупулёзны в этом вопросе. То, накидайте пожалуйста кодом, пример записи, вашей структуры данных, хотя бы в обычный массив. Возможно, кто-то заинтересуется и да подкинет, интересные идей :)

Отредактировано Webarion (30.08.2023 01:55:39)

0


Вы здесь » PureBasic - форум » PureBasic для Windows » Многомерные массивы переменной размерности