Russian Qt Forum
Сентябрь 21, 2024, 17:48 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Упаковка повторящихся указателей  (Прочитано 7847 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Май 19, 2010, 19:52 »

Добрый день

Имею массивы данных A и B. Каждый элемент массива B хранит переменное число указателей на данные массива А. Для всех элементов массива А существует хотя бы один указатель на него, хранимый в элементе массива В. Однако реально намного больше указателей (в разных элементах B) указывают на одни и те же данные А.
Пример

976,144 элементов в массиве А
9,761,502 указателей сохранено во всех элементах массива В

(1) 289               // 289 элементов массива В хранят 1 указатель
(2) 5768             // 5768 элементов массива В хранят 2 указателя
(3) 14624           // и.т.д
(4) 23738
(5) 23962
(6) 45696
(7) 50171
(8 ) 65778
(9) 60586
(10) 73359
(11) 53775
(12) 60424
(13) 23796
(14) 13969
(15) 3025
(16) 1295
(17) 530
(18) 2254
(19) 4689
(20) 29658
(21) 18392
(22) 13850
(23) 11127
(24) 10720
(25) 8902
(26) 5942
(27) 3557
(28) 2586
(29) 5726
(30) 1074
(31) 2631
(32) 29211
(33) 42531
(34) 691
(37) 10
(64) 712
(65) 59
(128) 1

Вопрос - как бы мне "упаковать" хранимые указатели чтобы они жрали меньше памяти? При этом, конечно, должна быть возможность перебирать все указатели хранящиеся в элементе B "почти" так же быстро как и сейчас

Спасибо


Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #1 : Май 20, 2010, 01:57 »

ты случаем не СУБД пишешь?
Записан

Юра.
spectre71
Гость
« Ответ #2 : Май 20, 2010, 08:44 »

Отношение многое ко многому.
В общем случае при достаточно случайном распределении - никак.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Май 20, 2010, 10:48 »

ты случаем не СУБД пишешь?
Нет, бог миловал.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Май 20, 2010, 17:27 »

Отношение многое ко многому.
В общем случае при достаточно случайном распределении - никак.
У меня тоже аж ни одной мысли  Показает язык Не коррелированы они никак, частотный словарь даст 5-10% - не стоит возиться. Обидно подымать лапки в верх как оте STL-вские зайчики  Обеспокоенный
Записан
spectre71
Гость
« Ответ #5 : Май 21, 2010, 09:42 »

Отношение многое ко многому.
В общем случае при достаточно случайном распределении - никак.
У меня тоже аж ни одной мысли  Показает язык Не коррелированы они никак, частотный словарь даст 5-10% - не стоит возиться. Обидно подымать лапки в верх как оте STL-вские зайчики  Обеспокоенный

10'000'000 индексов не так и много, если в данной задаче пиковое кол-во не будет существенно больше, то даже не стоит заморачиваться.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 21, 2010, 19:17 »

10'000'000 индексов не так и много, если в данной задаче пиковое кол-во не будет существенно больше, то даже не стоит заморачиваться.
Так это всего для миллиона элементов массива A, а их может быть и 10-20 млн
Записан
spectre71
Гость
« Ответ #7 : Май 22, 2010, 10:29 »

10'000'000 индексов не так и много, если в данной задаче пиковое кол-во не будет существенно больше, то даже не стоит заморачиваться.
Так это всего для миллиона элементов массива A, а их может быть и 10-20 млн

Если объем превысит некоторое установленное(или расчитанное) значение можно сохранять данные в файле и использавать "file mapping".
Например:
Цитировать
uchar * QFile::map ( qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions )
bool QFile::unmap ( uchar * address )
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 22, 2010, 10:58 »

Я тут подумал, кое-что вырисовывается. Рассмотрим очень упрощенный вариант: мы хотим упаковать всего 31 наиболее часто встречающихся указателя (ну или 63 в 64 битах). Тогда выходит так:

- отбираем 31 наиболее часто встречающихся указателя и помещаем их в отдельный массив С

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

- пакуем массив указателей: выкидываем из него все элементы которые есть в C, при этом взводим бит в маске.

- переписываем  массив - сначала записываем маску, потом все неупакованные указатели

- использование (когда нужно перебрать все указатели в В): проверяем является ли первый указатель маской. Младший бит взведен (нечетный адрес), значит это маска, выбираем указатели из С используя биты маски. Пример: маска 0x00A3, надо взять 0-й, 4-й и 6-й указатели из C

Пока неясно как завести более длинный "словарь С"


 
Записан
spectre71
Гость
« Ответ #9 : Май 22, 2010, 11:25 »

Я тут подумал, кое-что вырисовывается. Рассмотрим очень упрощенный вариант: мы хотим упаковать всего 31 наиболее часто встречающихся указателя (ну или 63 в 64 битах). Тогда выходит так:

- отбираем 31 наиболее часто встречающихся указателя и помещаем их в отдельный массив С

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

- пакуем массив указателей: выкидываем из него все элементы которые есть в C, при этом взводим бит в маске.

- переписываем  массив - сначала записываем маску, потом все неупакованные указатели

- использование (когда нужно перебрать все указатели в В): проверяем является ли первый указатель маской. Младший бит взведен (нечетный адрес), значит это маска, выбираем указатели из С используя биты маски. Пример: маска 0x00A3, надо взять 0-й, 4-й и 6-й указатели из C

Пока неясно как завести более длинный "словарь С"

Это имеет смысл если есть достаточное кол-во повторяющихся поднаборов индексов.
В этом случае словарей(C) можно сделать и больше.
1bit - указывает на тип индекса: 0 - прямой, 1-набор из словаря
если 0 - то индекс берем как есть
если 1 - то индекс берем из словаря
(Если тип индекса int32, то простая проверка на > или < 0)

Для словарного индекса, например:
15bit - номер словаря (32768 - словарей)
16bit - маска


« Последнее редактирование: Май 22, 2010, 11:27 от Spectre » Записан
spectre71
Гость
« Ответ #10 : Май 22, 2010, 11:32 »

Также не обязательно использовать всегда 15bit для номера словаря.
Для некоторых словарей может быть и другой расклад, например:
10bit - номер словаря
21bit - маска
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.052 секунд. Запросов: 22.