Re[7]: Сериализация в .NET. Выпрямляем своими руками
От: Andrbig  
Дата: 21.12.04 10:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Исхдники были приложены к статьи.


К бумажной статье был CD с исходниками, а на сайте — "покупайте наших слонов!", т.е. никакого кода.

VD>А вообще поробуй пошукать по форуму. Тут ссылки уже не раз проходили.


Page not found по этим ссылкам. Либо — вперед, в инет.
Re[2]: Сериализация в .NET. Выпрямляем своими руками
От: alex2808 Украина  
Дата: 21.12.04 11:35
Оценка:
Здравствуйте, Юнусов Булат, Вы писали:

ЮБ> public static DataSet GetDataSetMessages(byte[] data)

ЮБ> {
ЮБ> if (null != data)
ЮБ> {
ЮБ> MemoryStream ms = new MemoryStream(data);

ЮБ> DataSet ds = new Sior.Data.DataSetMessages();

ЮБ> ms.Seek(0, SeekOrigin.Begin);
ЮБ> ds.ReadXml(ms);
ЮБ> ds.AcceptChanges();
ЮБ> return ds;

ЮБ> }

ЮБ> return null;
ЮБ> }

Попробовал клас Булата...
Идея классная — DataSet переводит в массив байтов упаковывает его (потрясающе, раз в 100 сжимает), байтовый массив передается влет по сетке...
Но... вот тут то и началось...
Тестирую скорость все на тех же 20 тыс.строк.
Перевод byte[] в DataSet с помощью строки кода
ds.ReadXml(ms);

занимает около 3-х минут...
Операция сохранения из DataSet в byte[]
ds.WriteXml(ms);

всего 8-10 секунд.
Т.е. вся операция выгребки данных и передачи их на клиента с сервака занимает около 4-х минут... !!!!!

Если передавать чистый DataSet без упаковки, то на моем железе — чуть больше минуты...

Может кто-то объяснит парадокс???


З.ы. Я правда немного переделал функции Булата, вместо Sior.Data.DataSetMessages я везде подставил просто DataSet. Все работает... Может в этом и вся соль и это влияет на скорость преобразования?
Как Булат ответил, это у него параметризованный DataSet. Что это такое, и с чем его едят этот параметризованный ДатаСет, может кто подскажет... Где о нем почитать можно? Чем он отличается от обычного?
Всех благ
Re[8]: Сериализация в .NET. Выпрямляем своими руками
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.12.04 21:50
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>К бумажной статье был CD с исходниками, а на сайте — "покупайте наших слонов!", т.е. никакого кода.


Видимо код просто потеряли. Пстараюсь исправить эту проблему.
... << RSDN@Home 1.1.4 beta 3 rev. 267>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в .NET. Выпрямляем своими руками
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 22.12.04 04:27
Оценка:
Здравствуйте, Andrbig, Вы писали:

VD>>Исхдники были приложены к статьи.

A>К бумажной статье был CD с исходниками, а на сайте — "покупайте наших слонов!", т.е. никакого кода.

fixed
Re[9]: Сериализация в .NET. Выпрямляем своими руками
От: Andrbig  
Дата: 22.12.04 14:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Andrbig, Вы писали:


A>>К бумажной статье был CD с исходниками, а на сайте — "покупайте наших слонов!", т.е. никакого кода.


VD>Видимо код просто потеряли. Пстараюсь исправить эту проблему.


Ok, код появился. Ура!

Но также появился вопрос (по выделенным частям текста):
Byte ZipBase::Compress(System::Byte src[],Level level) __gc[]
{
    uLongf len = src->Length+100;
    Bytef * dest = new Bytef[len];
    Byte __pin *p = &src[0];

    int ret = compress2(dest,&len,p,src->Length,level);
    p = 0;
    switch (ret) {
    case Z_MEM_ERROR:    throw new System::Exception("There is not enough memory.");
    case Z_BUF_ERROR:    throw new System::Exception("There is not enough room in the output buffer.");
    case Z_STREAM_ERROR: throw new System::Exception("The level parameter is invalid.");
    case Z_OK: ;
    }

    Byte buf __gc[] = new Byte __gc[len];

    p = &buf[0];
    memcpy(p,dest,len);
    p = 0;

    delete [] dest;

    return buf;
}

dest выделяется, происходит исключение, dest не освобождается?
Re[10]: Сериализация в .NET. Выпрямляем своими руками
От: Аноним  
Дата: 22.12.04 16:29
Оценка: :))) :)
Здравствуйте, Andrbig, Вы писали:

A>dest выделяется, происходит исключение, dest не освобождается?


У статьи же название "Выпрямляем своими руками"
Re[10]: Сериализация в .NET. Выпрямляем своими руками
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.12.04 09:38
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>dest выделяется, происходит исключение, dest не освобождается?


Это к IT. Обертка его.
... << RSDN@Home 1.1.4 beta 3 rev. 267>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Сериализация в .NET. Выпрямляем своими руками
От: Аноним  
Дата: 31.03.06 20:08
Оценка:
Здравствуйте, Владислав Чистяков, Вы писали:

ВЧ>Статья:

ВЧ>Сериализация в .NET. Выпрямляем своими руками
Автор(ы): Владислав Чистяков
Дата: 02.09.2003
В статье приводятся тесты скорости сериализации и объема сериализованных данных при применении автоматической сериализации в .NET. Обсуждаются варианты исправления ситуации. В качестве примера приводится вариант ручной сериализации для объектов DataSet и DataTable.


ВЧ>Авторы:

ВЧ> Владислав Чистяков

ВЧ>Аннотация:

ВЧ>В статье приводятся тесты скорости сериализации и объема сериализованных данных при применении автоматической сериализации в .NET. Обсуждаются варианты исправления ситуации. В качестве примера приводится вариант ручной сериализации для объектов DataSet и DataTable.

Во второй версии фреймворка коновалы из МС не смогли сделать нормальную сериализацию для DataSet при DataSet.RemotingFormat == SerializationFormat.Binary;
Ну не уроды, а ? Проверка корректности датасета, используемая в тесте — падает на датах.
Re: Сериализация в .NET. Выпрямляем своими руками
От: Spiceman  
Дата: 10.04.08 10:11
Оценка: -1
Здравствуйте, Владислав Чистяков, Вы писали:

ВЧ>В статье приводятся тесты скорости сериализации и объема сериализованных данных при применении автоматической сериализации в .NET. Обсуждаются варианты исправления ситуации. В качестве примера приводится вариант ручной сериализации для объектов DataSet и DataTable.


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

Но меня удивили и насторожили результаты тестов. Выигрышь производительности в десятки раз это все таки не слабо.
Поэтому не поленился посмореть код. Оказалось, что структура, которая участвовала в тесте состоит из 4-х полей простых типов (числовые). А сериализация заключается просто в последовательной записи значений полей в поток. И эта функция сериализации годится только для данного класса.

Получается, что автор сравнивает в тестах 3 принципиально отличающихся алгоритма — свою простенькую сериализацию, форматтеры и xml-сериализатор. Но у этих трех алгоритмов принципиально разное предназначение! Я могу понять, когда сравниваются разные алгоритмы сортировки по скорости — в них решается одна задача. Но как можно сравнивать алгоритмы, решающие разные задачи??!! Это все равно, что сравнивать по скорости, например, алгоритм сжатия, алгоритм шифрования DES (симметричный) и алгоритм шифрования RSA (асимметричный). Все три алгорится на входе получают массив байт, на выходе выдают массив байт. И для всех трех можно провести обратную операцию восстановления исходного массива. Но разве корректно было бы их сравнивать по скорости? Да еще сделать свой алгоритм, который шифрует массив байт только определенной структуры и сравнить те три алгоритма со своим. Это же бред!

Еще раз повторюсь. Я не против того, чтобы использовать свою сериализацию для некоторых классов. Но я против того, чтобы сравнивать разные алгоритмы сериализации, так как у них разное предназначение. Ведь такое сравнение фактически вводит людей в заблуждение, так как они начинают думать, что в майкрософте реализовали такие кривые (медленные и генерящие много байтов) алгоритмы сериализации.
Зачем их сравнивать по производительности и размеру получаемого потока?
Что имел ввиду автор, говоря об исправлении ситуации? Какой ситуации?

PS. Извиняюсь, что поднял статью пятилетней давности. Иногда пробивает на почитать какую-нибудь статью с рсдн-а.
Re[2]: Сериализация в .NET. Выпрямляем своими руками
От: gbear Россия  
Дата: 10.04.08 11:02
Оценка: +2
Здравствуйте, Spiceman, Вы писали:

S>Поэтому не поленился посмореть код.


Лучше бы не поленились, и заглянули в код какого-нибудь ObjectWriter/Reader... благо, сейчас это можно. Тогда бы вопросы отпали сами по себе.

S>Получается, что автор сравнивает в тестах 3 принципиально отличающихся алгоритма — свою простенькую сериализацию, форматтеры и xml-сериализатор. Но у этих трех алгоритмов принципиально разное предназначение!


?! Каким образом, бинарный форматтер может извинить _такой_ перерасход по размеру выходного потока. Накладные расходы на "универсальность"? ~40%?! Ага...

И таки в чем "принципиальное" различие алгоритмов? В универсальности форматеров?

S>Что имел ввиду автор, говоря об исправлении ситуации? Какой ситуации?


ЕМНИП, "что сериализация в дотнете сделана очень неоптимально". Что, собственно и было продемонстрированно на примерах. Не верите примерам — полазте по исходным текстам framework'а.

---
С уважением, Сиваков Константин
Re[3]: Сериализация в .NET. Выпрямляем своими руками
От: Spiceman  
Дата: 10.04.08 12:00
Оценка:
Здравствуйте, gbear, Вы писали:

G>Лучше бы не поленились, и заглянули в код какого-нибудь ObjectWriter/Reader... благо, сейчас это можно. Тогда бы вопросы отпали сами по себе.

А у меня нет никаких вопросов.

S>>Получается, что автор сравнивает в тестах 3 принципиально отличающихся алгоритма — свою простенькую сериализацию, форматтеры и xml-сериализатор. Но у этих трех алгоритмов принципиально разное предназначение!


G>?! Каким образом, бинарный форматтер может извинить _такой_ перерасход по размеру выходного потока. Накладные расходы на "универсальность"? ~40%?! Ага...

Именно универсальность и может оправдать небольшой перерасход ресурсов. Почему думаю не нужно объяснять. А вот почему именно такой перерасход ресурсов — это уже нужно копать. В приведенных тестах бинарная сериализация на 30% (по размеру) хуже ручной. Часть этого объема я могу объяснить тем, что нужно сохранять информацию о типах. В данном случае информацию о типе коллекции и о типах элементов. Причем хранить информацию нужно о типе каждого элемента, так как объявление массива TestData[] ary, еще не означает, что все элементы будут именно типа TestData, а могут быть, например, наследниками этого типа.

В данных тестах на каждый элемент массива приходится примерно от 16 до 34 байтов (посчитано по полям + проверено в отладчике). Плюс 30% — это примерно от 5 до 11 байтов на элемент дополнительной информации, генерируемой бинарным форматтером. Не так уж и много для хранения информации о типе. То есть, накладные расходы получаются большими именно из-за того, что приведенная в тестах тестовая структура содержит очень мало информации — соизмеримо с добавляемой форматтером информацией о типе.
В качестве подтверждения своих слов, увеличил размер структуры, добавив в нее поля.
Результат: Custom = 19 041 406 байт, Binary = 20 441 662 байт.
И чем больше будет размер структуры, тем меньше будет разница между Custom и Binary.


G>И таки в чем "принципиальное" различие алгоритмов? В универсальности форматеров?

В частности в универсальности. Внимательнее прочтите мой предыдущий пост, я там кратко изложил различия. Вы ведь не будете спорить о разном назначении форматтеров и XMLSeralizer-а.

S>>Что имел ввиду автор, говоря об исправлении ситуации? Какой ситуации?


G>ЕМНИП, "что сериализация в дотнете сделана очень неоптимально". Что, собственно и было продемонстрированно на примерах.

А по мне так не было оно продемонстрировано.
Re[4]: Сериализация в .NET. Выпрямляем своими руками
От: gbear Россия  
Дата: 10.04.08 15:41
Оценка:
Здравствуйте, Spiceman, Вы писали:

S>Именно универсальность и может оправдать небольшой перерасход ресурсов.

Хренасе "небольшой"...

S>Почему думаю не нужно объяснять.

Нет уж... будте добры

S>Часть этого объема я могу объяснить тем, что нужно сохранять информацию о типах. В данном случае информацию о типе коллекции и о типах элементов. Причем хранить информацию нужно о типе каждого элемента, так как объявление массива TestData[] ary, еще не означает, что все элементы будут именно типа TestData, а могут быть, например, наследниками этого типа.


Ага... Собственно, мысль-то понятна... но, ЕМНИП, в тестах гоняются массивы struct'ов... В связи с чем вопрос... а с каких это пор, мы научились наследоваться от struct?


S>В качестве подтверждения своих слов...


В качетсве подтверждения своих слов, небольшой вопрос... ответ на который ниже по тексту...

Дано:

    [Serializable]
    public struct A
    {
        byte a;
    }

    [Serializable]
    public class B
    {
        byte a;
    }

    class Program
    {
        static void Main(string[] args)
        {
            byte[] a = new byte[1];
            byte[] b = new byte[2];

            A[] c = new A[1];
            A[] d = new A[2];

            //Инициируем не null'ами

            B[] e = {new B()};
            B[] f = {new B(), new B()};
        }
    }


Догадайтесь, чему будет равна по парная разница (b-a, d-c и f-e) длин потоков, в которые мы данные массивы сериализуем бинарным форматтером.

Так вот... 1, 10 и 15 соотвественно... Попробуете объяснить?
При этом, сериализованный c[0] по длине равен e[0] и на целых 64 байта длиннее чем a[0].
Если же ввести

    [Serializable]
    public struct C 
    {
        byte a;
        byte b;
    }


то при сериализации массива таких структур, по сравнению с массивом структур типа A длина потока увеличится всего лишь на 1 байт / на элемент.
Но, при этом, если мы сериализуем c[0] и, гипотетический g[0] типа C — разница будет 5 байт.

Правда круто?

G>>И таки в чем "принципиальное" различие алгоритмов? В универсальности форматеров?

S>В частности в универсальности.

Универсальность, знаете ли, бывает и с "человеческим лицом", а не с такой вот гримасой.

G>>ЕМНИП, "что сериализация в дотнете сделана очень неоптимально". Что, собственно и было продемонстрированно на примерах.

S>А по мне так не было оно продемонстрировано.

Ну, на вкус и цвет, как говориться...

---
С уважением, Сиваков Константин.
Re[5]: Сериализация в .NET. Выпрямляем своими руками
От: Spiceman  
Дата: 10.04.08 19:36
Оценка:
Здравствуйте, gbear, Вы писали:

S>>Именно универсальность и может оправдать небольшой перерасход ресурсов.

G>Хренасе "небольшой"...
А вы читали что я написал? 7 процентов перерасхода на метаданные — это много? Я же написал, что все зависит от размера сериализуемой структуры. Ручная сериализация имеет смысл, когда размер метаданных соизмерим с объемом самих данных.

PS. Хочется все таки вести более конструктивный диалог. Для этого я разделил этот диалог на несколько нитей.
Re[5]: Сериализация в .NET. Выпрямляем своими руками
От: Spiceman  
Дата: 10.04.08 19:36
Оценка: -1
Здравствуйте, gbear, Вы писали:

S>>Почему думаю не нужно объяснять.

G>Нет уж... будте добры
Дополнительные ресурсы требуются для сохранения метаданных о сериализуемом типе. Эта информация будет использована для десериализации.
В ручной сериализации сохранять метаданные смысла нет, так как эта информация о типе задается в самом алгоритме сериализации.

G>Догадайтесь, чему будет равна по парная разница (b-a, d-c и f-e) длин потоков, в которые мы данные массивы сериализуем бинарным форматтером.

G>Так вот... 1, 10 и 15 соотвественно... Попробуете объяснить?
Да что тут объяснять. Разный объем требуется для сохранения разных метаданных. Почему именно такие числа — значит именно столько требуется, чтобы в метаданных сохранить информацию о том, что элементы первого массива — байты, воторого — структура A, а третьего — класс B. Причем я не уверен, но вполне возможно, что для классов требуется сохранять несколько больше информации. Но в любой случае именно столько ее и требуется для того, чтобы можно было потом восстановить.
Разбираться с тем, почему получается именно столько байт честно не хочется. Но уверен, что специалисты майкрософта многое предусмотрели и раз байтов получается именно столько, значит столько и нужно. По крайней мере ни в статье, ни в этой ветке на форуме я не нашел опровержения.

G>Правда круто?

Круто Ага
Re[5]: Сериализация в .NET. Выпрямляем своими руками
От: Spiceman  
Дата: 10.04.08 19:36
Оценка:
Здравствуйте, gbear, Вы писали:

G>>>И таки в чем "принципиальное" различие алгоритмов? В универсальности форматеров?

S>>В частности в универсальности.
G>Универсальность, знаете ли, бывает и с "человеческим лицом", а не с такой вот гримасой.
Опять же не нашел ни в статье ни в этой ветке, в чем же заключается эта гримаса.
Но дело ведь не только в универсальности. Вы не читали мое сообщение. Дело в том, что ручная сериализация, форматтеры и XMLSerializer не являются взаимозаменямыми и используются для различных целей. Вы же не используется алгоритм шифрования, когда вам нужно сжатие.

Я вообще никак не могу понять, в чем вы со мной не согласны. Я так понимаю, что у вас основная мысль в том, что бинарный форматтер реализован не оптимально. Не буду с этим спорить. Может и не оптимально. Может быть его можно было реализовать производительней. Изучение тонких мест алгоритма BinaryFormatter-а — это целая отдельная тема для статьи.

Моя же основная критика этой статьи заключается в том, что сравнивать производительность можно только у взаимозаменяемых алгоритмов. Например, можно сравнить два различных алгоритма сортировки массивов, а потом придумать свой алгоритм более производительный и запатентовать его. Но сравнивать между собой алгоритмы, предназначенные для разных целей (не взаимозаменяемые) нельзя. Никому ведь в голову не придет использовать форматтеры для того, чтобы создать XML документ. А если и придет, то ничего у него не получится.
Надеюсь моя мысль понятна?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.