вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 18.08.04 07:11
Оценка:
Уважаемый Олл,

С .net я только начинаю знакомиться, но с сериализацией я знаком давно
по MFC. И там еще у меня возник вопрос, на который я ответа не нашел.
Предполагаю, что и здесь его нет, но все же, может, кто-то скажет
интересное.
Для понятности задачу слегка упростил. В действительности все было
намного сложнее.

Есть класс — двумерная матрица. Матрица сильно разрежена. Ее надо
сохранить, но нули сохранять не надо.

Для сохранения предлагется простейший формат

Целое N3 — число троек.
Первая тройка — i,j, value
Вторая тройка — i,j, value
И т.д.

Насколько я понимаю, здесь надо сериализоваться с написанием собственной
ISerializable.GetObjectData
и специального конструктора. Хорошо.

Проблема же вот в чем. Я не знаю N3. Я его узнаю, только когда
просканирую матрицу и подсчитаю число ненулевых элементов. А вывести его
надо сначала, иначе потом я не при десериализации не буду знать, сколько
троек читать.

(Конечно, есть вариант с записью в конец ограничителя — чего-то вроде
(0,0,0). Здесь он проходит, но, напоминаю, исходная задача была намного
сложнее. Так что этот вариант не рассматривается).

Получается, что алгоритм двухпроходной. На первом проходе находим N3, на
втором — записываем тройки.

Если бы вместо сериализации я просто в файл писал — алгоритм
однопроходной. Пропускаем в файле 4 байта для N3, записываем тройки
(одновременно считаем N3) , позиционируемся назад к позиции N3,
записываем ее.

Можно ли сделать алгоритм однопроходным при сериализации ?

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re: вопрос по сериализации
От: Holmes Россия  
Дата: 18.08.04 07:20
Оценка:
Pavel,

А как насчет варианта заранее иметь количество заполненных ячеек в матрице?

Удачи, Сергей.
Re[2]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 18.08.04 07:33
Оценка:
Привет!

Holmes wrote:
>
> Pavel,
>
> А как насчет варианта заранее иметь количество заполненных ячеек в матрице?

Согласен, в данном случае это возможно, но , напоминаю, исходная задача
была намного сложнее. Если хочешь, немного деталей. Матрица была
трехмерной, и вертикали в ней состояли из ненулевых кусков, вот эти
куски надо было и выводить, причем при выводе анализировалось, не был ли
такой же кусок (т.е того же размера и с такими же значениями) выведен
раньше в другой вертикали, и если да — он не выводился, а делалась
ссылка на его позицию в файле. Это все несколько минут занимало . Что
поделать, размер матрицы был огромный (порядка 5000*5000*200) и в ОП она
никогда целиком не хранилась.


--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re: вопрос по сериализации
От: Apollo13 Украина  
Дата: 18.08.04 07:52
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>Если бы вместо сериализации я просто в файл писал — алгоритм

PD>однопроходной. Пропускаем в файле 4 байта для N3, записываем тройки
PD>(одновременно считаем N3) , позиционируемся назад к позиции N3,
PD>записываем ее.

Как насчет во время сериализации записать все что нужно в ArrayList и сериализовать его?
Re[2]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 18.08.04 08:07
Оценка:
Привет!

Apollo13 wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:
>
> PD>Если бы вместо сериализации я просто в файл писал — алгоритм
> PD>однопроходной. Пропускаем в файле 4 байта для N3, записываем тройки
> PD>(одновременно считаем N3) , позиционируемся назад к позиции N3,
> PD>записываем ее.
>
> Как насчет во время сериализации записать все что нужно в ArrayList и сериализовать его?

Ох нет, только не это . Там десятки, если не сотни Мб. См. пояснение
в моем ответе Holmes

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[3]: вопрос по сериализации
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.04 09:09
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Матрица была

PD>трехмерной, и вертикали в ней состояли из ненулевых кусков, вот эти
PD>куски надо было и выводить, причем при выводе анализировалось, не был ли
PD>такой же кусок (т.е того же размера и с такими же значениями) выведен
PD>раньше в другой вертикали, и если да — он не выводился, а делалась
PD>ссылка на его позицию в файле.

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

PD> Это все несколько минут занимало . Что

PD>поделать, размер матрицы был огромный (порядка 5000*5000*200) и в ОП она
PD>никогда целиком не хранилась.

А насколько она разрежена? Может быть есть смысл эмулировать матрицу на хэш-таблице? Например, в экселе делается именно так. Правда с трехмерной прийдется повозиться, но все же.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 18.08.04 09:30
Оценка:
Привет!

VladD2 wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:

<skipped>

> А насколько она разрежена? Может быть есть смысл эмулировать матрицу на хэш-таблице? Например, в экселе делается именно так. Правда с трехмерной прийдется повозиться, но все же.


Похоже, дело свелось к обсуждению того, как лучше эту матрицу хранить и
выводить. Не это меня интересует, а другое.

Можно ли при сериализации с собственной реализацией GetObjectData
передвигаться в потоке ? Т.е. оставить место , а потом к нему вернуться
и записать значение. Например

Оставить место для A
Вывести B
Вывести C
Вывести D
Вернуться и записать A
Вернуться в позицию после D

В общем, аналогично FileStream.Position

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[5]: вопрос по сериализации
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.08.04 12:42
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Похоже, дело свелось к обсуждению того, как лучше эту матрицу хранить и

PD>выводить. Не это меня интересует, а другое.

Дык именно неверное представление в первую очередь бросается в глаза.

PD>Можно ли при сериализации с собственной реализацией GetObjectData

PD>передвигаться в потоке ? Т.е. оставить место , а потом к нему вернуться
PD>и записать значение.

Ты волен создать свой поток и делать с ним что душа пожелает. Бинари- и Соап-форматер принимают именованные значения через SerializationInfo.AddValue(). Подсунь туда свой массив байтов или стрим.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: вопрос по сериализации
От: Lloyd Россия  
Дата: 18.08.04 12:50
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

А почему бы просто не писать в MemoryStream. А после просто вызвать метод GetBuffer и получить все что ты туда записал в виде массива байт.
Re: вопрос по сериализации
От: Poudy Россия  
Дата: 18.08.04 16:46
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD> ...[skipped]...


PD>Есть класс — двумерная матрица. Матрица сильно разрежена. Ее надо

PD>сохранить, но нули сохранять не надо.

PD>Насколько я понимаю, здесь надо сериализоваться с написанием собственной

PD>ISerializable.GetObjectData
PD> и специального конструктора. Хорошо.
При сериализации в Net в поток пишешь не ты. Собственно... порядок параметров не важен.

Сделай так:

ArrayList rowsList = new ArrayList(/*~N*/);
.... // добавление троек.

int[][] rows = rowsList.ToArray(typeof(int[])) as int[][];
или
int[,] rows = ....

info.AddValue("rows", rows);

ну а N, вообще говоря, теперь и не нужно никуда писать.
Re[6]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 19.08.04 05:14
Оценка:
Привет!

VladD2 wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:
>
> PD>Похоже, дело свелось к обсуждению того, как лучше эту матрицу хранить и
> PD>выводить. Не это меня интересует, а другое.
>
> Дык именно неверное представление в первую очередь бросается в глаза.

Ну и бог с ним . Я ведь не об этом спрашиваю, а о сериализации.

>

> PD>Можно ли при сериализации с собственной реализацией GetObjectData
> PD>передвигаться в потоке ? Т.е. оставить место , а потом к нему вернуться
> PD>и записать значение.
>
> Ты волен создать свой поток и делать с ним что душа пожелает. Бинари- и Соап-форматер принимают именованные значения через SerializationInfo.AddValue(). Подсунь туда свой массив байтов или стрим.

А вот здесь, если можно, поподробнее. Мне самому вчера эта мысль в
голову пришла. Идея следующая

Открываем свой поток
Класс имплементирует ISerializable
В GetObjectData делаю следующее
AddValue(произвольное целое)
Position1 = Stream.Position // запомнили позицию
Теперь в цикле прохожу матрицу и заношу по AddValue все тройки и считаю
их количество — N3
Position2 = Stream.Position // запомнили позицию
Stream.Position = Position1
AddValue(N3) // записали вместо произвольного целого N3
Stream.Position = Position2 // и вернулись в конец

Это корректно ?


--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[2]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 19.08.04 05:22
Оценка:
Привет!

Lloyd wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:
>
> А почему бы просто не писать в MemoryStream. А после просто вызвать метод GetBuffer и получить все что ты туда записал в виде массива байт.

Не совсем понял. MemoryStream, как я понимаю, находится в ОП, так ? Т.е.
ты предлагаешь сначала туда записать, а потом взять байты и их
сериализовать ? Это решение не пройдет — объем данных ОЧЕНЬ большой и
НИКАКОЕ копирование их по ходу сериализации просто недопустимо.
Я понимаю (даже с моим знанием .net , что можно придумать еще много
других решений. Вообще, если этот вопрос рассматривать чисто
практически, то разумное решение находится за 1 минуту — выкинуть это N3
вообще, а в конце записать тройку (0,0,0) . Мой вопрос в другом —
можно ли перемещаться по потоку при сериализации ? Иными словами ,
сериализация — строго последовательный алгоритм или все же можно в нем
позиционироваться ?
См. также мой ответ VladD2

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[2]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 19.08.04 05:24
Оценка:
Привет!

Poudy wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:
>
> PD> ...[skipped]...
>
> PD>Есть класс — двумерная матрица. Матрица сильно разрежена. Ее надо
> PD>сохранить, но нули сохранять не надо.
>
> PD>Насколько я понимаю, здесь надо сериализоваться с написанием собственной
> PD>ISerializable.GetObjectData
> PD> и специального конструктора. Хорошо.
> При сериализации в Net в поток пишешь не ты. Собственно... порядок параметров не важен.
>
> Сделай так:
>
> ArrayList rowsList = new ArrayList(/*~N*/);
> .... // добавление троек.

Никакое копирование при сериализации недопустимо по причине ограничений
по памяти. См. также мои другие сегодняшние ответы.


--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[5]: вопрос по сериализации
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.04 08:43
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

>> А насколько она разрежена? Может быть есть смысл эмулировать матрицу на хэш-таблице? Например, в экселе делается именно так. Правда с трехмерной прийдется повозиться, но все же.


PD>Похоже, дело свелось к обсуждению того, как лучше эту матрицу хранить и

PD>выводить.

Потому что проблема именно в этом.

PD>Можно ли при сериализации с собственной реализацией GetObjectData

PD>передвигаться в потоке ?

Нет, потому что не любой поток допускает позиционирование.
... << RSDN@Home 1.1.4 beta 2 rev. 162>>
AVK Blog
Re[6]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 19.08.04 08:51
Оценка:
Привет!

AndrewVK wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:
>
> >> А насколько она разрежена? Может быть есть смысл эмулировать матрицу на хэш-таблице? Например, в экселе делается именно так. Правда с трехмерной прийдется повозиться, но все же.
>
> PD>Похоже, дело свелось к обсуждению того, как лучше эту матрицу хранить и
> PD>выводить.
>
> Потому что проблема именно в этом.
>
> PD>Можно ли при сериализации с собственной реализацией GetObjectData
> PD>передвигаться в потоке ?
>
> Нет, потому что не любой поток допускает позиционирование.

А если в GetObjectData проверять контекст и разрешать, только если это
File ?

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[7]: вопрос по сериализации
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.08.04 09:25
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А если в GetObjectData проверять контекст и разрешать, только если это

PD>File ?

Боюсь механика кастомной сериализации универсальная и на подобные извращения не рассчитана. Вобщем тебе правильно тут советуют — либо храни свою матрицу ввиде хешей (а для разреженной матрицы именно этот способ хранения является оптимальным), либо формируй список вершин со значениями в памяти целиком.

P.S. И сокращай лишнее цитирование.
... << RSDN@Home 1.1.4 beta 2 rev. 162>>
AVK Blog
Re[8]: вопрос по сериализации
От: Pavel Dvorkin Россия  
Дата: 19.08.04 09:28
Оценка:
Привет!

AndrewVK wrote:
>
> Здравствуйте, Pavel Dvorkin, Вы писали:

> Боюсь механика кастомной сериализации универсальная и на подобные извращения не рассчитана. Вобщем тебе правильно тут советуют — либо храни свою матрицу ввиде хешей (а для разреженной матрицы именно этот способ хранения является оптимальным), либо формируй список вершин со значениями в памяти целиком.


Понятно. Все это не проходит, так как матрица была взята только для
пояснения сути проблемы, реальную проблему я описал в одном из ответов.
Ну что же, раз нельзя, значит, нельзя.
--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[7]: вопрос по сериализации
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.08.04 11:08
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Это корректно ?


Просто сохрани нужное тебе число с отдельным именем. А с другим именем сохрани ссылку на стрим. Когда будешь читать, то читай и то и другое, а потом уже читай свой стрим.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: вопрос по сериализации
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.08.04 11:08
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Нет, потому что не любой поток допускает позиционирование.


Да нет поблем сохранить нужную величину под отдельным именем. И по стримам прыгать не прицдется.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: вопрос по сериализации
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.08.04 11:08
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

Ты бы цитаты вырезал. А то очень неудобно читать одну строчку. Скролировать больше приходится. Да и БД не резиновая.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.