Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Не совсем понял. MemoryStream, как я понимаю, находится в ОП, так ? Т.е. PD>ты предлагаешь сначала туда записать, а потом взять байты и их PD>сериализовать ? Это решение не пройдет — объем данных ОЧЕНЬ большой и PD>НИКАКОЕ копирование их по ходу сериализации просто недопустимо.
Думаю ты преувеличивашь проблему. Объем данных будет значительно меньше твоей матрицы. К тму же есть своп. Если что ОС займет место в нем.
В конце концов сегда вместоа стрима можно использовать дисковый файл и стрин на его основе.
Создать простую реализацию тебе ничего не стоит. Попробуй, а потом будеш делать выводы. Поменять реализацию никогда не поздно.
И помни, сериализация в дотнете очень не эффективная. Если ты создашь свой стрим, то резко повысишь производительность и понизишь расход памяти. Так что...
Кстати, зачем тебе сериализация? Для каки целей?
PD>Я понимаю (даже с моим знанием .net , что можно придумать еще много PD>других решений. Вообще, если этот вопрос рассматривать чисто PD>практически, то разумное решение находится за 1 минуту — выкинуть это N3 PD>вообще, а в конце записать тройку (0,0,0) .
Во-во. И тормоза с перерасходм памяти выростят на порядок, так как стандартная сериализация дико не эффективна.
PD> Мой вопрос в другом - PD>можно ли перемещаться по потоку при сериализации ?
Зависит от потока. Стандартная сериализация вообще не предоставляет тебе никаких потоков. Она предлагает создать тебе граф обхектов или заполнить словарь (имя->значение). Сериализация же при этом делается дотнетом (системными библиотеками). Нужно это для двух вещей. 1. Это позволяет решить проблему чтения сериализованной информации другой версии. 2. Это позволяет абстрагироваться от формата сериализации и, например, сохраняь данные в ХМЛ. Но это довольно не эффективно, плюс ко всему, орлы из МС реализовали этот механизм из рук вон плохо. Так что лучше сериализовать вручную, в тот самый мемори-стрим (или файл). А потом или просто использовать этот стрим, или подсовывать его стандартному сериализатору.
PD> Иными словами , PD>сериализация — строго последовательный алгоритм или все же можно в нем PD>позиционироваться ?
Ни то, ни то. Ответ выше.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Нет, потому что не любой поток допускает позиционирование.
VD>Да нет поблем сохранить нужную величину под отдельным именем. И по стримам прыгать не прицдется.
Ты не понял — он хочет в стрим сначала записать количество, потом данные, притом количество он заранее не знает, а держать все данные в памяти или делать два прохода не хочет.
Здравствуйте, AndrewVK, Вы писали:
AVK>Ты не понял — он хочет в стрим сначала записать количество, потом данные, притом количество он заранее не знает, а держать все данные в памяти или делать два прохода не хочет.
Я все понял. Но как ты понимашь стримов там просто нет. Так что его один фиг вручную создавать. А если так, то количество можно хранить и под отдельным именем.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
PD>Ох нет, только не это . Там десятки, если не сотни Мб. См. пояснение PD>в моем ответе Holmes
1. Так ведь десятки разреженных мегабайт?
2. Сериализация в дотнете работает очень небыстро. При сериализации нет доступа к бинарному виду, все виртуализировано до уровня именованых свойств.
Если ты хочешь в бинарном виде сохранять, делай так.
* Создай MemoryStream, в конструкторе задай примерную вместимость (прикинь, какой процент ячеек обычно заполнен, добавь чуток сверху).
* Беги по матрице, сбрасывай понемногу данные.
* Получи MemoryStream.ToArray и скинь его сериализационному механизму в один именованый слот.
* Скинь размер в другой именованый слот.
PD>Если хочешь, немного деталей. Матрица была PD>трехмерной, и вертикали в ней состояли
Тогда действительно лучшим решением будет создать правильное хранилище для этой матрицы (которое используется в Run-Time), и потом сериализовать его стандартным образом, вообще без custom ISerializable implementation.
Теоретически, нужно те столбцы или колонки, которые ты там используешь, реализовать отдельным внутренним классом, и учитывать по нему некий хеш.
И реализовывать механизм Copy-On-Write. При попытке изменения данных в объекте-столбце, смотреть на то, используетя ли он "в нескольких позициях". Если да, то делать копию, и уменьшать счетчик. То есть при возникновении изменений совместно используемый столбец будет "расслаиваться", дивергенция.
Хеширование нужно для того, чтобы сделать обратный механизм, "конвергенцию". Когда в результате изменений два разных столбца начинают хранить одинаковые данные, их можно объединить и одну копию данных выбросить.
Чтобы производительность была высокой, хеширование должно быть простым (можно XOR или сумму всех элементов). Тогда при изменении одной ячейки в столбце не нужно будет пересчитывать весь хеш, а только произвести две обратные операции -- отнять старое значение, прибавить новое. Когда при изменении ячейки хеш вдруг начинает совпадать с другим столбцом, нужно удостовериться что столбцы действительно полностью совпадают, и тогда их совмещать и удалять дубль.
Такое бережливое отношение к памяти ускорит и runtime-обработку, так как скорость перезагрузки процессорных кешей обычно очень критична для обсчетов.