Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.04.03 00:36
Оценка: 292 (23) +1
Всем привет!

Я уже на раз говорил, о том что сериализация в дотнете сделана очень не оптимально. Данная тема является научным доказательством правоты моих слов. Итак, я сделал тест в котором создается массив структур размеров в сто тысяч элементов (ну, шоб було чё мерить) который сиреализуется с помощью:
* BinaryFormatter-а.
* Рукопашной бинарной сериализации.
* SoapFormatter-а.

При этом выводится время сериализации и размер полученных данных.

Но и это еще не все! (с) Какая-то реклама.

Я нарыл какой-то левый ActivX-контрол — ActiveZip (как я подключал его к нету это отдельная песня ...) и зазиповал им полученные данные. Этот тупой активыкс умеет зиповать только в файл. Ну, да это мелочи.

Вот результаты смелого эксперимента советских ученых (время в миллисекундах, размер в байтах):
BinaryFormatter serialization time elapsed:  1 132, Length is: 5 041 592
Binary manual formatted serialization time elapsed:   60, Length is: 3 641 406
SoapFormatter serialization time elapsed:  3 415, Length is: 12 285 041

SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 56.92  <-- !!! Поглядите на это 
BinaryFormatter zip time elapsed:  1 472,

BinaryManual zip time elapsed:   971,
SoapFormatter zip time elapsed:  1 182,


А вот размеры зипов:
testBinaryFormatter.zip — 1 690 884
testBinaryManual.zip — 1 209 830
testSoapFormatter.zip — 1 875 791

Скажу честно, если говорить о размерах данных, то я думал о бинарном форматере несколько хуже. Бинарный форматер умудряется создать всего на четверть более пухлый чем следовало бы. Но по скорости форматеры дотнета не выдерживают никакой критики. Разница в десятки раз (около 20 между бинарными и 60 (!) между соап и бинарным). В общем поубивал бы.

И это притом, что сеарилизацией по сути дела заведует сам компилятор!

Зипование несколько скрашивает грустную ситуацию, но все же. Даже зипованый файл на 40-50 процентов больше идеального. Плюс больше время за зазиповку.

Вы только представьте! За время сериализации BinaryFormatter-ом можно успеть не только сериализовать, но и зазиповать данные, уменьшив их в 3 раза! в А ведь при зиповке данные еще к тому же записывались на диск!

Соап форматер по времени вообще убийственен.

Выводы

Сначала немного разбавим темные краски. Все же в этом тесте сериализовались относительно большие объемы данных. Обычно приходится иметь дело с данными в десять, а то и в сто раз меньшими по объему. Учитывая, что процессоры более-менее шустрые на маленьких объемах можно стерпеть и 60-и кратные тормоза. Однако на сервере, учитывая, что каждый пользователь умножает объем обрабатываемой информации, это может стать серьезной проблемой. Причем не зная приведенных мной данных, скорее всего тормоза будут списаны на JIT-компиляцию и другие инсинуации.

Ремоутинг и комплюс... Именно их, данная проблема задевает в первую очередь. Дело в том, что при маршалинге данные сериализуются. А значит время, потраченное на этот процесс, замедляет работу ремоутинга. Раздутый результат сериализации только усугубляет ситуацию.

DataSet. Отдельной проблемой является DataSet. Дело в том, что DataSet всегда сериализуются в XML. Даже если его попросить сериализоваться в бинари-форматер, он все равно сериализуются в XML, а только потом получившуюся текстовую строку записывает в форматер.

Кто виноват? И что делать?

Ну, виноват известно кто... Мокрософт. На такую важную вещь как сериализация можно было бы потратить больше усилий и средств.

А вот что делать? Дотнет 1.1 не решает проблему. Ждать же более новой версии дотнета еще очень долго, да и скорее всего проблема в нем снова не будет решена. Единственное что может заставить МС заняться сериализацией — это каой-нить конкурент. Например, Сан может заявить, что Ява сериализует объекты в ХХХ раз быстрее... И тогда Буквально через пол года дотнетная сериализаци станет круче паровоза. Однако верится в это с трудом. Так что нужно брать все в свои руки.

Пути... В первую очередь можно написать ручную сериализацию для наиболее часто используемых объектов хранящих/передающих большие объемы данных. DataSet просто напрашивается на, то чтобы первым надругались над ним. Вернее не над ним, а на одной из его составных — над DataTable. Ведь именно этот класс хранит реальные данные.

1. В идеале нужно сделать код автоматической сериализации для произвольного объекта. С моей (сильно абстрактной) колокольни это видится так:
Пишется небольшой класс, который для каждого типа на лету создает (с помощью System.Reflection.Emit) код сериализации. Это позволит, потратив немного времени на начальном этапе получить практически идеальную (по всем параметрам) сериализацию.

2. Вопреки моде и рекламе стараться передавать по сети бинарные данные. Причем не грех будет и попытаться сжать данные (но делать это нужно осторожно, так как процесс этот ресурсоемкий). Тот же DataSet можно сериализовать в бинарный вид даже при передаче по http. При этом можно использовать или формат base64, или (что еще лучше) стандарт DIME (позволяющий делать бинарные вложения в http-запрос). Красота и читаемость XML-я в данном случае совершенно недужна. Признайтесь честно часто вы просматриваете сетевые пакеты? В конце концов, всегда можно превратить данные в XML и полюбоваться на них. А вот на диске можно хранить и XML. Если его много, лучше не пользоваться соап-форматером. Найдите где-нибудь намного более эффективных SAX-парсер и разбирайте данные им. Однако занятие это не легкое. И если проблем с производительностью нет, лучше не искать проблем на свою голову. Бесполезно пытаться ускорить процесс разбора XML-я и DOM-парсерами. По крайней мере, тот, что входит в дотнет работает еще медленнее, чем соап-форматер.

Ну, и последний вопрос. Стоит ли ломать копья? Шестидесяти кратная разница в скорости может убедить кого угодно. Особенно если пользователи уже начинают подвывать. Например, похожая проблема назревает в rsdn@houme. Несколько хоумщиков одновременно выбирающие сообщения за день могут серьезно и довольно на долго затормозить сервер. А ведь страдают от этого в основном онлайнщики. Ведь хоумщик в это время пьют чай.

SP

Пользуясь, случаем передаю привет АВК и всем кто считает что сериализация в нете сделана нормально.

Код теста (C#):

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
// Это ком-объект-обертка над ActiveZip сделанная на VB6. Без нее он валится. :(
// Возможно дело в том, что этот компонент хочет лежать на форме.
using TestCom;

namespace SerializeTest
{
    /// <summary>
    /// Подопытная структура. Из нее создается массив которы 
    /// нужно сериализовать.
    /// </summary>
    [Serializable]
    public struct TestData
    {
        // Данные...
        public int _i1;
        public int _i2;
        public double _f1;
        public string _s1;

        /// <summary>
        /// Ручная сериализация.
        /// Сериализует содержимое массива структур TestData в стрим.
        /// </summary>
        /// <param name="ms">Стрим куда сериализуются данные</param>
        /// <param name="ary">Массив</param>
        public static void Write(MemoryStream ms, TestData[] ary)
        {
            BinaryWriter bw = new BinaryWriter(ms);
            Int32 iLen = ary.Length;
            bw.Write(iLen);
            for(int i = 0; i < iLen; i++)
            {
                bw.Write(ary[i]._i1);
                bw.Write(ary[i]._i2);
                bw.Write(ary[i]._f1);
                bw.Write(ary[i]._s1);
            }
        }

        /// <summary>
        /// Ручная сериализация.
        /// Создает массив структур TestData и считывает в него информацию
        /// из стрима.
        /// </summary>
        /// <param name="ms">Стрим в котором находится сериализованное
        /// представление массива структур (созданное с помощю метда Write).</param>
        /// <returns></returns>
        public static TestData[] Read(MemoryStream ms)
        {
            BinaryReader br = new BinaryReader(ms);
            Int32 iLen = br.ReadInt32();
            TestData[] ary = new TestData[iLen];
            for(int i = 0; i < iLen; i++)
            {
                ary[i]._i1 = br.ReadInt32();
                ary[i]._i2 = br.ReadInt32();
                ary[i]._f1 = br.ReadDouble();
                ary[i]._s1 = br.ReadString();
            }
            return ary;
        }

        /// <summary>
        /// Создает и инициализирует массив структур TestData
        /// </summary>
        /// <param name="ArrayLen">Количество элементов в массиве</param>
        /// <returns>Заполненный массив</returns>
        public static TestData[] InitErray(int ArrayLen)
        {
            TestData[] aryTd = new TestData[ArrayLen];
            for(int i = 0; i < ArrayLen; i++)
            {
                aryTd[i]._f1 = i * 1.3;
                aryTd[i]._i1 = i;
                aryTd[i]._i2 = i * 2;
                aryTd[i]._s1 = "Стр" + i.ToString() + " " + (i * 234).ToString();
            }
            return aryTd;
        }
    }

    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            int start; // Используется для вычисления времени выполнения

            // Стрим для сериализации через BinaryFormatter
            MemoryStream msBf = new MemoryStream(10*1000*1000);
            // Стрим для ручной сериализации.
            MemoryStream msBm = new MemoryStream(10*1000*1000);
            // Стрим для сериализации через SoapFormatter
            MemoryStream msSf = new MemoryStream(10*1000*1000);
            BinaryFormatter bf = new BinaryFormatter();
            SoapFormatter sf = new SoapFormatter();

            // Массив структур который будет сериализоваться
            TestData[] aryTestData = TestData.InitErray(100*1000);

            // Сериализация BinaryFormatter-ом
            start = Environment.TickCount;
            bf.Serialize(msBf, aryTestData);
            Console.WriteLine(
                "BinaryFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start, msBf.Length);

            // Сериализация врукопашную
            start = Environment.TickCount;
            TestData.Write(msBm, aryTestData);
            int BinaryManualTime = Environment.TickCount - start;
            Console.WriteLine(
                "Binary manual formatted serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                BinaryManualTime, msBm.Length);

            // Сериализация SoapFormatter-ом
            start = Environment.TickCount;
            sf.Serialize(msSf, aryTestData);
            int SoapFormatterTime = Environment.TickCount - start;
            Console.WriteLine(
                "SoapFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                SoapFormatterTime, msSf.Length);

            // Выводим разницу между бинарной и соапной сериализацией.
            Console.WriteLine("SoapFormatter.Length / BinaryManual.Length = {0:0.00}",
                msSf.Length * 1.0 / msBm.Length);
            Console.WriteLine("SoapFormatter.Time / BinaryManual.Time = {0:0.00}",
                SoapFormatterTime * 1.0 / BinaryManualTime);

            TestCom.Class1Class test = new TestCom.Class1Class();

            //////////////////////////////////////////////////////////////////////////
            // Зипуем...

            string zipName;
            string binName;
            FileStream fs;

            // Зипуем данные полученные BinaryFormatter-ом
            start = Environment.TickCount;
            zipName = Environment.CurrentDirectory + @"\testBinaryFormatter.zip";
            binName = Environment.CurrentDirectory + @"\testBinaryFormatter";
            fs = new FileStream(binName, FileMode.Create);
            msBf.WriteTo(fs);
            fs.Close();
            test.ZipData(zipName, binName);
            Console.WriteLine(
                "BinaryFormatter zip time elapsed: {0:### ### ###}, ",
                Environment.TickCount - start);

            // Зипуем данные полученные вручную.
            start = Environment.TickCount;
            zipName = Environment.CurrentDirectory + @"\testBinaryManual.zip";
            binName = Environment.CurrentDirectory + @"\testBinaryManual";
            fs = new FileStream(binName, FileMode.Create);
            msBm.WriteTo(fs);
            fs.Close();
            test.ZipData(zipName, binName);
            Console.WriteLine(
                "BinaryManual zip time elapsed: {0:### ### ###}, ",
                Environment.TickCount - start);

            // Зипуем данные полученные SoapFormatter-ом
            start = Environment.TickCount;
            zipName = Environment.CurrentDirectory + @"\testSoapFormatter.zip";
            binName = Environment.CurrentDirectory + @"\testSoapFormatter";
            fs = new FileStream(binName, FileMode.Create);
            msSf.WriteTo(fs);
            fs.Close();
            test.ZipData(zipName, binName);
            Console.WriteLine(
                "SoapFormatter zip time elapsed: {0:### ### ###}, ",
                Environment.TickCount - start);

            Console.ReadLine();
        }
    }
}


Обертака для ActiveZip (VB6):
' Class1
Option Explicit
  
Public Sub ZipData(ByVal ZipFilename As String, ByVal AddFilename As String)
    Form1.ZipData ZipFilename, AddFilename
    Unload Form1
End Sub

' Form1 свойство Visible этой формы выставлено в false (шобы ее небыло вдно).
' Возможно я и перемудрил. Может быть достаточно было бросить этот кривой объект
' на WinForms-ую форму. Теперь пределываьть уже влом.
Option Explicit

Public Sub ZipData(ByVal ZipFilename As String, ByVal AddFilename As String)
    ActiveZip1.CreateZip ZipFilename, ""
    Dim iLen As Long
    ActiveZip1.AddFile AddFilename, ""
    ActiveZip1.PreservePaths = False
    ActiveZip1.Close
End Sub
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Сериализация в дотнете
От: IT Россия linq2db.com
Дата: 10.04.03 00:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я нарыл какой-то левый ActivX-контрол — ActiveZip (как я подключал его к нету это отдельная песня ...) и зазиповал им полученные данные. Этот тупой активыкс умеет зиповать только в файл.


Могу кинуть обёрнутый в .NET zlib.

VD>Кто виноват? И что делать?


А просто написать свой форматтер и использовать его в Remoting разве не получится?
... << RSDN@Home 1.0 beta 6a >>
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.04.03 00:58
Оценка:
Здравствуйте, IT, Вы писали:

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


VD>>Я нарыл какой-то левый ActivX-контрол — ActiveZip (как я подключал его к нету это отдельная песня ...) и зазиповал им полученные данные. Этот тупой активыкс умеет зиповать только в файл.


IT>Могу кинуть обёрнутый в .NET zlib.


Давай. На мыло, плиз. И сам zlib тоже. Прикрутим (по позже) к хоуму.

VD>>Кто виноват? И что делать?


IT>А просто написать свой форматтер и использовать его в Remoting разве не получится?


Я не разбирался с форматерами. Возможно и можно. Но это будет не "просто".
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сериализация в дотнете
От: IT Россия linq2db.com
Дата: 10.04.03 01:07
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Могу кинуть обёрнутый в .NET zlib.


VD>Давай. На мыло, плиз. И сам zlib тоже.


Ok, сейчас поищу.

VD>Прикрутим (по позже) к хоуму.


Если хоуму выставить чего-нибудь через ремоутинг, то можно будет прикрутить как раз нормальный форматтер.

IT>>А просто написать свой форматтер и использовать его в Remoting разве не получится?


VD>Я не разбирался с форматерами. Возможно и можно. Но это будет не "просто".


Проще наверное будет как раз с этим разобраться.
... << RSDN@Home 1.0 beta 6a >>
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.04.03 07:55
Оценка:
Здравствуйте, IT, Вы писали:

VD>>Прикрутим (по позже) к хоуму.


IT>Если хоуму выставить чего-нибудь через ремоутинг, то можно будет прикрутить как раз нормальный форматтер.


Так что — забиваем тогда на сервис и переходим на ремоутинг?
... << RSDN@Home 1.0 beta 6a >>
AVK Blog
Re[3]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.04.03 07:55
Оценка: 4 (2)
Здравствуйте, VladD2, Вы писали:

IT>>Могу кинуть обёрнутый в .NET zlib.


VD>Давай. На мыло, плиз. И сам zlib тоже. Прикрутим (по позже) к хоуму.


http://www.icsharpcode.net/OpenSource/SharpZipLib/

Здесь 100% managed упаковщик
... << RSDN@Home 1.0 beta 6a >>
AVK Blog
Re[4]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.04.03 14:01
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>http://www.icsharpcode.net/OpenSource/SharpZipLib/


AVK>Здесь 100% managed упаковщик


Дык то что дал ИТ тоже полностью компилируется в менеджед-код. МС++ как всегда выручает.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Сериализация в дотнете
От: mihailik Украина  
Дата: 10.04.03 14:58
Оценка: 19 (2)
VD>Пишется небольшой класс, который для каждого типа на лету создает (с помощью System.Reflection.Emit) код сериализации. Это позволит, потратив немного времени на начальном этапе получить практически идеальную (по всем параметрам) сериализацию.

Такие утилиты вообще-то положено по кругу пускать, чтобы лучше различать тенденцию и начальные выбросы. Хотя в данном случае особых выбросов нету.

Добавил XML Serialization.

BinaryFormatter serialization time elapsed:  1 752, Length is: 5 041 578
Binary manual formatted serialization time elapsed:   80, Length is: 3 641 406
SoapFormatter serialization time elapsed:  4 817, Length is: 12 285 027
XmlSerializerTime serialization time elapsed:  2 734, Length is: 13 295 651 (chars)
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 60.21


Пришлось убрать ZIP, так как у меня его нету. В результате получается, что XML Serialization примерно посредине между Binary и SOAP. А по объёму чуть больше SOAP.
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.04.03 16:54
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Добавил XML Serialization.


Дык пость код суда. Я прогоню на той же машине... Можно даже малюсенькую статейку состряпать.

M>Пришлось убрать ZIP, так как у меня его нету. В результате получается, что XML Serialization примерно посредине между Binary и SOAP. А по объёму чуть больше SOAP.


Все равно скорость даже у бинари никуда не годится.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.04.03 18:17
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Все равно скорость даже у бинари никуда не годится.


Эх Влад, не все так там просто. Форматтер != сериалайзер. У форматтера куча наворотов что бы это все в ремоутинге работало и кучу типов маршалило, так что написать свой форматтер будет не очень легко.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[5]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 10.04.03 18:21
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Дык то что дал ИТ тоже полностью компилируется в менеджед-код. МС++ как всегда выручает.


Тебе IT ведь написал что это оболочка над zlib.dll.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 12:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Тебе IT ведь написал что это оболочка над zlib.dll.


Это сам zlib перекомпилированный под дотнет.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 12:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Эх Влад, не все так там просто. Форматтер != сериалайзер. У форматтера куча наворотов что бы это все в ремоутинге работало и кучу типов маршалило, так что написать свой форматтер будет не очень легко.


Кто бы спорил. Но сделать ручную сериализацию для того же Датасета можно. И относительно не сложно.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сериализация в дотнете
От: nob113  
Дата: 11.04.03 14:10
Оценка:
Gospoda, a moget nu ee, etu serializatsiu ?

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml03172003.asp


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

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


AVK>Эх Влад, не все так там просто. Форматтер != сериалайзер. У форматтера куча наворотов что бы это все в ремоутинге работало и кучу типов маршалило, так что написать свой форматтер будет не очень легко.


VD>Кто бы спорил. Но сделать ручную сериализацию для того же Датасета можно. И относительно не сложно.
Re[6]: Сериализация в дотнете
От: nob113  
Дата: 11.04.03 14:16
Оценка:
Konechno, obidno kogda ona vdelannaya — i tut uge ne otvertishsya, no po krainei mere, inogda mogno oboitis' i bez nee...

Est' takay ideya sozdat' compensatsionni proekt — sodergaishi functsionalnost', neobodimost' kotoroi ochevisna....

Eto klassnya ideya IXPathable like — estl' i u kogo narabotki ?

Cheers.




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

N>Gospoda, a moget nu ee, etu serializatsiu ?


N>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml03172003.asp



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


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


AVK>Эх Влад, не все так там просто. Форматтер != сериалайзер. У форматтера куча наворотов что бы это все в ремоутинге работало и кучу типов маршалило, так что написать свой форматтер будет не очень легко.


VD>Кто бы спорил. Но сделать ручную сериализацию для того же Датасета можно. И относительно не сложно.
Re[4]: Сериализация в дотнете
От: mihailik Украина  
Дата: 11.04.03 15:06
Оценка:
VD>>Все равно скорость даже у бинари никуда не годится.

AVK>Эх Влад, не все так там просто. Форматтер != сериалайзер. У форматтера куча наворотов что бы это все в ремоутинге работало и кучу типов маршалило, так что написать свой форматтер будет не очень легко.


Да, разные там MethodReturnMessage. Видимо, поэтому XML Serialization быстрее SoapFormatter получается.

Вот добавление в коде:
                // Сериализация XmlSerializer-ом
                start = Environment.TickCount;
                StringWriter xmlOut=new StringWriter();
                xmlSer.Serialize(
                    xmlOut,
                    aryTestData );
                int XmlSerializerTime = Environment.TickCount - start;
                Console.WriteLine(
                    "XmlSerializerTime serialization time elapsed: {0:### ### ###}, "
                    + "Length is: {1:### ### ###} (chars)",
                    XmlSerializerTime, xmlOut.ToString().Length );


Вставлял сразу за блоком "// Сериализация SoapFormatter-ом".
... << RSDN@Home 1.0 beta 6a >>
Re: Сериализация в дотнете
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 11.04.03 17:07
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>* BinaryFormatter-а.

VD>* Рукопашной бинарной сериализации.
VD>* SoapFormatter-а.

Не корректно сравнивать Formatter-ы и рукопашнюю бинарную сериализацию (по крайней мере в том виде, в котором она сделана у тебя).

стандартные Formatter-ы поддерживают:
1. смену версий классов (добавление, удаление полей)
2. сохранение объектного графа с произвольной структурой

Измение механизма serialize-ации для отдельных подчастей сохраняемого объектного графа может приводить к глюкам,
например, это видно на следующем примере:

public class Row
{
}

public class Main
{
  public Table table = new Table();
  public Row row;
}

//у этого класс свой личный serializer
public class Table
{
  public Row row;
}

void Test()
{
  Main main = new Main();
  main.row = main.table.row = new Row();  

  Save(main);
  Main main2 = Load();
  
}


В этом примере, если у класс B мы написали свой хитрый serializer, а сохраняли весь класс Main.
То получится, что main2 будет с другой структурой (будет две копии Row), чем main
... << RSDN@Home 1.0 beta 6 >>
Re[2]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.04.03 19:16
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>стандартные Formatter-ы поддерживают:

DG>1. смену версий классов (добавление, удаление полей)
DG>2. сохранение объектного графа с произвольной структурой
3. Кастомные биндеры
4. Сериализацию TransparentProxy
5. formatter sinks
6. Сериализационные суррогаты
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[5]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.04.03 19:16
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Да, разные там MethodReturnMessage. Видимо, поэтому XML Serialization быстрее SoapFormatter получается.


XmlSerializer быстрее еще потому что во первых не использует DOM парсер, во вторых сериализующий класс генериться в конструкторе, а затем при сериализации рефлекшен почти не используется.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[5]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.04.03 19:20
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Кто бы спорил. Но сделать ручную сериализацию для того же Датасета можно. И относительно не сложно.


Чтобы это работало в ремоутинге нужно писать кастомную сериализацию на основе ISerializable, а это, как показывает практика, сильного выигрыша не дает. Есдинственный выход — явно сериализовать, не используя инфраструктуру нета и передавать в качестве параметров массив байтов.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[7]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 11.04.03 19:20
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Тебе IT ведь написал что это оболочка над zlib.dll.


VD>Это сам zlib перекомпилированный под дотнет.


Могу кинуть обёрнутый в .NET zlib.


Так обернутый или перекомпилированный?
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[8]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>

AVK>Могу кинуть обёрнутый в .NET zlib.


AVK>Так обернутый или перекомпилированный?


То что он прислал — это исходники zlib. В свойствах проекта стоит "с цлр экстеншоном". Серьезнее не смотрел.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Чтобы это работало в ремоутинге нужно писать кастомную сериализацию на основе ISerializable, а это, как показывает практика, сильного выигрыша не дает.


Если криво присать, то да. Все очень просто. Нужно не добавлять все как в доках написано, а создать стрим и закатать его по одним именем. Тогда (думаю) все будет пучечком.

AVK>Есдинственный выход — явно сериализовать, не используя инфраструктуру нета и передавать в качестве параметров массив байтов.


Это в крайнем случае.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:40
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>XmlSerializer быстрее еще потому что во первых не использует DOM парсер, во вторых сериализующий класс генериться в конструкторе, а затем при сериализации рефлекшен почти не используется.


Я бы на их месте вообще бы код сериализации для типа на лету один раз генерил, а потом его использовал.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:40
Оценка:
Здравствуйте, mihailik, Вы писали:

Зачем ты стринг ратйте использовал? Ну, да ладно. Махнул на обычный стрим...

Итак, результаты:

BinaryFormatter serialization time elapsed:  1 121, Length is: 5 041 593
Binary manual formatted serialization time elapsed:   70, Length is: 3 641 406
SoapFormatter serialization time elapsed:  3 245, Length is: 12 285 042
XmlSerializerTime serialization time elapsed:  2 003, Length is: 13 595 633
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 46.36
BinaryFormatter zip time elapsed:  1 412,
BinaryManual zip time elapsed:   921,
SoapFormatter zip time elapsed:  1 112,
XmlSerializer zip time elapsed:  1 041,


Забавно, что хотя размер у XmlSerializer-а больше жмется он лучше.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:40
Оценка:
Здравствуйте, DarkGray, Вы писали:

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


VD>>* BinaryFormatter-а.

VD>>* Рукопашной бинарной сериализации.
VD>>* SoapFormatter-а.

DG>Не корректно сравнивать Formatter-ы и рукопашнюю бинарную сериализацию (по крайней мере в том виде, в котором она сделана у тебя).


Это же почему? Очень даже корректно. А разница на два порядка — это вообще не в какие ворота.

DG>стандартные Formatter-ы поддерживают:

DG>1. смену версий классов (добавление, удаление полей)

Попробуй бинарным форматером считать данные записанные другой версией.
К тому же при той же передаче по сети версия ненужна.

Поддерживают? Молодцы. Путь отключать научатся когда это не нужно.

А текстовые. Ну, эти и в правду с версиями по лучше работают. Вот только оправдывает ли в 90% случаев такой пререрасход эти приемущетсва?

DG>2. сохранение объектного графа с произвольной структурой


Чушь. Попробуй сериализовать Hashtable. Сам все поймешь. При ручной сериализации мжно куда более сложные вещи вытварять. Ну и в любом случае разницу в скорости на порядки это не оправдывает.

DG>Измение механизма serialize-ации для отдельных подчастей сохраняемого объектного графа может приводить к глюкам,

DG>например, это видно на следующем примере:...

DG>В этом примере, если у класс B мы написали свой хитрый serializer, а сохраняли весь класс Main.

DG>То получится, что main2 будет с другой структурой (будет две копии Row), чем main

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


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

Я указал на то что скорость у автоматической сериализации очень низкая и на то, что размер (особенно в хмл) здоровый. А приемущества... Да есть они конечно. Вот только нужны они тебе, например, когда ты объект средствами ремоутинга по сетке передаешь?
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.04.03 20:48
Оценка:
Здравствуйте, AndrewVK, Вы писали:

DG>>1. смену версий классов (добавление, удаление полей)

DG>>2. сохранение объектного графа с произвольной структурой

Эти пункты легко реализуются вручную. Наш ascDB поддерживает версии на обычном стриме. Перерасход — несколько байт и один их. Учитывая, что BinaryWriter в дотнете тоже написан через одно место (все постоено на операторах >> вместо работы с адресами и копирования памяти), скорость будет еще выше чем в дотнете. С сохранением дерева объектов тоже проблем нет.

Проблема только одна. Все довольно сложно.

AVK>3. Кастомные биндеры


Правильно. Шоб було!

AVK>4. Сериализацию TransparentProxy


Вообще не в кассу. Транспарент прокси сам использут то что ему подсунут. Измени сериализацию в датасете и будет он TransparentProxy-ёй в лучшем виде сериализоваться.

AVK>5. formatter sinks


Опять так куда без них. Все только с ними и работают. Жаль не многи значют что это и зачем надо.

AVK>6. Сериализационные суррогаты


Это и я не знают что это.

В общем тяхело вам принять информацию о том, что не смотря на красоту реализация у сериализации в дотнете никуда не годится.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в дотнете
От: IT Россия linq2db.com
Дата: 11.04.03 22:02
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Так обернутый или перекомпилированный?


Перекомпилированный в managed код и обёрнутый в managed класс

ЗЫ. Твой вариант мне нравится больше, во-первых нативностью, во-вторых, поддержкой других форматов, в-третьих, свежестью в отличии от дремучего десятилетнего zlib.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 00:24
Оценка: 6 (1)
Здравствуйте, VladD2, Вы писали:

Новая версия теста.
Изменения:
1. Добавлен
2. Левый zip-ующий ActiveX заменен на zlib (менеджед обертка, внутри скомпилированная в native-код zlib и легкая manadged-обертка).
Тест проведен с разными типами сжатия. Сжатие теперь производится в файл.

Уровень сжатия BestSpeed почти незаметно по стравнению со временем сериализации стандартных сериалайзеров. Интересно, что они там делают? Надо будет поглядеть...

Уровень сжатия DefaultCompression несмертельно медленнее, но дает очень высокую степень сжатия.

Уровень сжатия BestCompression заимает слишком много времени, а рельного выигрыша в степени сжатия не дает. Хотя даже время сжатия на этом уровкне оказалось меньше чем сериализация SoapFormatter-форматером.

В общем можно долго рассуждать о том, что я не учел время затрачиваемое на вычисления графа объектов и неучел версионность, но такие тормоза неможет объяснить ни одна отмазка. Даже зип значительно быстрее самого быстрого форматера. А уж он то делает куда больше полезных вычислений.

BestCompression

BinaryFormatter serialization time elapsed:  1 192, Length is: 5 041 592
Binary manual formatted serialization time elapsed:   70, Length is: 3 641 406
SoapFormatter serialization time elapsed:  3 455, Length is: 12 285 041
XmlSerializerTime serialization time elapsed:  2 053, Length is: 13 595 633
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 49.36
Зазиповываем. Уровень сжатия: BestCompression
BinaryFormatter zip time elapsed:  4 606, Ziped size: 1 690 067
BinaryManual zip time elapsed:  3 025, Ziped size: 1 209 452
SoapFormatter zip time elapsed:  3 535, Ziped size: 1 808 222
XmlSerializer zip time elapsed:  3 144, Ziped size: 1 551 295


BestSpeed

BinaryFormatter serialization time elapsed:  1 192, Length is: 5 041 592
Binary manual formatted serialization time elapsed:   70, Length is: 3 641 406
SoapFormatter serialization time elapsed:  3 445, Length is: 12 285 041
XmlSerializerTime serialization time elapsed:  2 033, Length is: 13 595 633
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 49.21
Зазиповываем. Уровень сжатия: BestSpeed
BinaryFormatter zip time elapsed:   310, Ziped size: 1 777 824
BinaryManual zip time elapsed:   231, Ziped size: 1 353 346
SoapFormatter zip time elapsed:   390, Ziped size: 2 204 262
XmlSerializer zip time elapsed:   371, Ziped size: 1 934 505

DefaultCompression

BinaryFormatter serialization time elapsed:  1 141, Length is: 5 041 592
Binary manual formatted serialization time elapsed:   61, Length is: 3 641 406
SoapFormatter serialization time elapsed:  3 354, Length is: 12 285 041
XmlSerializerTime serialization time elapsed:  1 993, Length is: 13 595 633
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 54.98
Зазиповываем. Уровень сжатия: DefaultCompression
BinaryFormatter zip time elapsed:  1 262, Ziped size: 1 690 669
BinaryManual zip time elapsed:   831, Ziped size: 1 209 622
SoapFormatter zip time elapsed:   852, Ziped size: 1 875 580
XmlSerializer zip time elapsed:   791, Ziped size: 1 609 710


Новая версия кода

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
using Zlib;

namespace SerializeTest
{
    /// <summary>
    /// Подопытная структура. Из нее создается массив которы 
    /// нужно сериализовать.
    /// </summary>
    [Serializable]
    public struct TestData
    {
        // Данные...
        public int _i1;
        public int _i2;
        public double _f1;
        public string _s1;

        /// <summary>
        /// Ручная сериализация.
        /// Сериализует содержимое массива структур TestData в стрим.
        /// </summary>
        /// <param name="ms">Стрим куда сериализуются данные</param>
        /// <param name="ary">Массив</param>
        public static void Write(MemoryStream ms, TestData[] ary)
        {
            BinaryWriter bw = new BinaryWriter(ms);
            Int32 iLen = ary.Length;
            bw.Write(iLen);
            for(int i = 0; i < iLen; i++)
            {
                bw.Write(ary[i]._i1);
                bw.Write(ary[i]._i2);
                bw.Write(ary[i]._f1);
                bw.Write(ary[i]._s1);
            }
        }

        /// <summary>
        /// Ручная сериализация.
        /// Создает массив структур TestData и считывает в него информацию
        /// из стрима.
        /// </summary>
        /// <param name="ms">Стрим в котором находится сериализованное
        /// представление массива структур (созданное с помощю метда Write).</param>
        /// <returns></returns>
        public static TestData[] Read(MemoryStream ms)
        {
            BinaryReader br = new BinaryReader(ms);
            Int32 iLen = br.ReadInt32();
            TestData[] ary = new TestData[iLen];
            for(int i = 0; i < iLen; i++)
            {
                ary[i]._i1 = br.ReadInt32();
                ary[i]._i2 = br.ReadInt32();
                ary[i]._f1 = br.ReadDouble();
                ary[i]._s1 = br.ReadString();
            }
            return ary;
        }

        /// <summary>
        /// Создает и инициализирует массив структур TestData
        /// </summary>
        /// <param name="ArrayLen">Количество элементов в массиве</param>
        /// <returns>Заполненный массив</returns>
        public static TestData[] InitErray(int ArrayLen)
        {
            TestData[] aryTd = new TestData[ArrayLen];
            for(int i = 0; i < ArrayLen; i++)
            {
                aryTd[i]._f1 = i * 1.3;
                aryTd[i]._i1 = i;
                aryTd[i]._i2 = i * 2;
                aryTd[i]._s1 = "Стр" + i.ToString() + " " + (i * 234).ToString();
            }
            return aryTd;
        }
    }

    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            int start; // Используется для вычисления времени выполнения

            // Стрим для сериализации через BinaryFormatter
            MemoryStream msBf = new MemoryStream(10*1000*1000);
            // Стрим для ручной сериализации.
            MemoryStream msBm = new MemoryStream(10*1000*1000);
            // Стрим для сериализации через SoapFormatter
            MemoryStream msSf = new MemoryStream(10*1000*1000);
            // Стрим для сериализации через XmlSerializer
            MemoryStream msXs = new MemoryStream(10*1000*1000);

            // Массив структур который будет сериализоваться
            TestData[] aryTestData = TestData.InitErray(100*1000);

            // Сериализация BinaryFormatter-ом
            start = Environment.TickCount;
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(msBf, aryTestData);
            Console.WriteLine(
                "BinaryFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start, msBf.Length);

            // Сериализация врукопашную
            start = Environment.TickCount;
            TestData.Write(msBm, aryTestData);
            int BinaryManualTime = Environment.TickCount - start;
            Console.WriteLine(
                "Binary manual formatted serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                BinaryManualTime, msBm.Length);

            // Сериализация SoapFormatter-ом
            start = Environment.TickCount;
            SoapFormatter sf = new SoapFormatter();
            sf.Serialize(msSf, aryTestData);
            int SoapFormatterTime = Environment.TickCount - start;
            Console.WriteLine(
                "SoapFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                SoapFormatterTime, msSf.Length);

            // Сериализация XmlSerializer-ом
            start = Environment.TickCount;
            XmlSerializer xmlSer = new XmlSerializer(aryTestData.GetType());
            //StringWriter xmlOut = new StringWriter();
            xmlSer.Serialize(msXs, aryTestData);
            int XmlSerializerTime = Environment.TickCount - start;
            Console.WriteLine(
                "XmlSerializerTime serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                XmlSerializerTime, msXs.Length );



            // Выводим разницу между бинарной и соапной сериализацией.
            Console.WriteLine("SoapFormatter.Length / BinaryManual.Length = {0:0.00}",
                msSf.Length * 1.0 / msBm.Length);
            Console.WriteLine("SoapFormatter.Time / BinaryManual.Time = {0:0.00}",
                SoapFormatterTime * 1.0 / BinaryManualTime);

            //////////////////////////////////////////////////////////////////////////
            // Зипуем...

            ZipBase.Level leve = ZipBase.Level.BestSpeed;
            byte[] aryZip; // Массив в который происходит сжатие.
            
            Console.WriteLine("Зазиповываем. Уровень сжатия: {0}", leve);


            // Зипуем данные полученные BinaryFormatter-ом
            start = Environment.TickCount;
            aryZip = ZipBase.Compress(msBf.ToArray(), leve);
            Console.WriteLine(
                "BinaryFormatter zip time elapsed: {0:### ### ###}, "
                + "Ziped size: {1:### ### ###}",
                Environment.TickCount - start, aryZip.Length);

            // Зипуем данные полученные вручную.
            start = Environment.TickCount;
            aryZip = ZipBase.Compress(msBm.ToArray(), leve);
            Console.WriteLine(
                "BinaryManual zip time elapsed: {0:### ### ###}, "
                + "Ziped size: {1:### ### ###}",
                Environment.TickCount - start, aryZip.Length);

            // Зипуем данные полученные SoapFormatter-ом
            start = Environment.TickCount;
            aryZip = ZipBase.Compress(msSf.ToArray(), leve);
            Console.WriteLine(
                "SoapFormatter zip time elapsed: {0:### ### ###}, "
                + "Ziped size: {1:### ### ###}",
                Environment.TickCount - start, aryZip.Length);

            // Зипуем данные полученные XmlSerializer-ом
            start = Environment.TickCount;
            aryZip = ZipBase.Compress(msXs.ToArray(), leve);
            Console.WriteLine(
                "XmlSerializer zip time elapsed: {0:### ### ###}, "
                + "Ziped size: {1:### ### ###}",
                Environment.TickCount - start, aryZip.Length);

            Console.ReadLine();
        }
    }
}
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 01:37
Оценка:
Здравствуйте, IT, Вы писали:

IT>Перекомпилированный в managed код и обёрнутый в managed класс


Я разобрался. Сам код обычный. Для фалов zlib-а вручную выключена компиляция в менеджед код.

Кстати, в обертке была ошибка. Тот кто ее писал не задал размер выходного буфекра и при прпытке зазиповать вываливалась ошибка. Я поправил это дело.

IT>ЗЫ. Твой вариант мне нравится больше, во-первых нативностью, во-вторых, поддержкой других форматов, в-третьих, свежестью в отличии от дремучего десятилетнего zlib.


Тем не менее функциональность у него хорошая. Сжимает неплохо. Скорость высокая. Интерфейс простой. Что еще для счястя надо?
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 01:37
Оценка:
Здравствуйте, VladD2, Вы писали:

Попробовал вместо zlib использовать SharpZipLib.

BZip просто вылетел.
GZip вроде заработал. Но у него никаких настроек и работает медленнее:
BinaryFormatter serialization time elapsed: 1 182, Length is: 5 041 592
Binary manual formatted serialization time elapsed: 80, Length is: 3 641 406
SoapFormatter serialization time elapsed: 3 365, Length is: 12 285 041
X
mlSerializerTime serialization time elapsed: 2 003, Length is: 13 595 633
SoapFormatter.Length / BinaryManual.Length = 3.37
SoapFormatter.Time / BinaryManual.Time = 42.06
Зазиповываем. Уровень сжатия: DefaultCompression
BinaryFormatter zip time elapsed: 1 272, Ziped size: 1 690 671
BinaryManual zip time elapsed: 831, Ziped size: 1 209 622
BinaryManual zip time elapsed: 1 151, GZip!! size: 1 209 637
SoapFormatter zip time elapsed: 842, Ziped size: 1 875 580
X
mlSerializer zip time elapsed: 781, Ziped size: 1 609 710
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 01:38
Оценка:
Здравствуйте, VladD2, Вы писали:

В общем старичек zlib + MC++ + МЫ 2003
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 07:14
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>3. Кастомные биндеры


VD>Правильно. Шоб було!


Ремоутинг без этого жить не может

AVK>>4. Сериализацию TransparentProxy


VD>Вообще не в кассу. Транспарент прокси сам использут то что ему подсунут. Измени сериализацию в датасете и будет он TransparentProxy-ёй в лучшем виде сериализоваться.


В кассу — форматтер должен по ней достать у ремоутинга ObjRef и сериализовать его.

AVK>>5. formatter sinks


VD>Опять так куда без них.


В ремоутинге опять никуда. Влад, форматтеры универсальны и обязаны обладать очень богатым функционалом. Еще раз повторюсь — форматтер это нечто большее чем сериализатор. Чистый сериализатор в нете один — XmlSerializer, вот с ним и сравнивай.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 07:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Забавно, что хотя размер у XmlSerializer-а больше жмется он лучше.


Он не пишет в xml идентификаторы объектов.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[7]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 07:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я бы на их месте вообще бы код сериализации для типа на лету один раз генерил, а потом его использовал.


Дык так и сделано. Поэтому XmlSerializer требует явного указания всех типов, которые могут быть задействованы. Вот было бы неплохо написать аналогичный BinarySrrializer, а не пытаться сделать свой быстрый и универсальный форматтер.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[7]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 07:22
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Чтобы это работало в ремоутинге нужно писать кастомную сериализацию на основе ISerializable, а это, как показывает практика, сильного выигрыша не дает.


VD>Если криво присать, то да.


Там писать то особо нечего. В общем если считаешь что я написал криво напиши сам и оцени результат. Тормоза у форматтеров отнюдь не из-за сериализации как таковой.

VD>Все очень просто. Нужно не добавлять все как в доках написано, а создать стрим и закатать его по одним именем. Тогда (думаю) все будет пучечком.


Проверь.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[10]: Сериализация в дотнете
От: IT Россия linq2db.com
Дата: 12.04.03 12:45
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>Перекомпилированный в managed код и обёрнутый в managed класс


VD>Я разобрался. Сам код обычный. Для фалов zlib-а вручную выключена компиляция в менеджед код.


Это сделано для совместимости. Если мне не изменяет мой склероз, там были проблемы со старыми сишными объявлениями. Я не стал ничго править в zlib'овских исходниках, а просто вырубил /clr. Если наплевать на совместимость с zlib (один фиг она уже лет десять не меняется), то можно кое что подрехтовать ручками и всё сделать в clr. Если очень нужно, то могу сделать.

VD>Кстати, в обертке была ошибка. Тот кто ее писал не задал размер выходного буфекра и при прпытке зазиповать вываливалась ошибка. Я поправил это дело.


Вообще что ли не зипует

IT>ЗЫ. Твой вариант мне нравится больше, во-первых нативностью, во-вторых, поддержкой других форматов, в-третьих, свежестью в отличии от дремучего десятилетнего zlib.


VD>Тем не менее функциональность у него хорошая. Сжимает неплохо. Скорость высокая. Интерфейс простой. Что еще для счястя надо?


К тому же большинство других зиповых либ сделано на её основе
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Сериализация в дотнете
От: IT Россия linq2db.com
Дата: 12.04.03 12:47
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>В общем старичек zlib + MC++ + МЫ 2003


Ну так может оформить это в потребный вид и выложить в файлы?
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 16:28
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ну так может оформить это в потребный вид и выложить в файлы?


Ща сделаем. Можно выложить на сидк. Сделаем подборку зипов.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 16:28
Оценка:
Здравствуйте, IT, Вы писали:

IT>Это сделано для совместимости. Если мне не изменяет мой склероз, там были проблемы со старыми сишными объявлениями. Я не стал ничго править в zlib'овских исходниках, а просто вырубил /clr. Если наплевать на совместимость с zlib (один фиг она уже лет десять не меняется), то можно кое что подрехтовать ручками и всё сделать в clr. Если очень нужно, то могу сделать.


А оно надо? Скорость нормальна. Все работает...

IT>Вообще что ли не зипует


Возвращала ошибку "недостаточный размер буфера".
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 16:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Там писать то особо нечего. В общем если считаешь что я написал криво напиши сам и оцени результат. Тормоза у форматтеров отнюдь не из-за сериализации как таковой.


Лучше не обижайся, а послушай.

Ты для каждого поля вызывал их функцию сериализации. А нужно добавить одно виртальное поле и засандалить в него стрим или массив байтов.

VD>>Все очень просто. Нужно не добавлять все как в доках написано, а создать стрим и закатать его по одним именем. Тогда (думаю) все будет пучечком.


AVK>Проверь.


Ладно. Сделаю статью про сериализацию... за одно протестирую.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 16:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Дык так и сделано. Поэтому XmlSerializer требует явного указания всех типов, которые могут быть задействованы. Вот было бы неплохо написать аналогичный BinarySrrializer, а не пытаться сделать свой быстрый и универсальный форматтер.


Дык XmlSerializer в два раза медленее чем BinarySrrializer.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 16:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>>>3. Кастомные биндеры


VD>>Правильно. Шоб було!


AVK>Ремоутинг без этого жить не может


Чуш. Ему нужно чтобы объект сериализовался, а как по большему счету его не трогает.

AVK>В кассу — форматтер должен по ней достать у ремоутинга ObjRef и сериализовать его.


Ладно. Позже проведу эксперементы. В конеце концов масив байт проскакивает со свистом.

AVK>В ремоутинге опять никуда.


Да-да...

AVK>Влад, форматтеры универсальны и обязаны обладать очень богатым функционалом. Еще раз повторюсь — форматтер это нечто большее чем сериализатор. Чистый сериализатор в нете один — XmlSerializer, вот с ним и сравнивай.


Разницы в скорости между ними нет. Да и ремоутинг в лучшем виде работает через ISerializable.

И вообще меня никто и никога не сможет убедить, что разница в скорости в два порядка может быть хоть чем-то аргументирована. Единственное объяснение — это бездарные алгоритмы.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 17:51
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Это сделано для совместимости. Если мне не изменяет мой склероз, там были проблемы со старыми сишными объявлениями. Я не стал ничго править в zlib'овских исходниках, а просто вырубил /clr. Если наплевать на совместимость с zlib (один фиг она уже лет десять не меняется), то можно кое что подрехтовать ручками и всё сделать в clr. Если очень нужно, то могу сделать.


VD>А оно надо? Скорость нормальна. Все работает...


Оно не будет верифицироваться. Если янус пустить не под админом то загрузить эту сборку в другой домен не получиться.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[9]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 17:51
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Дык XmlSerializer в два раза медленее чем BinarySrrializer.


То есть ты BinarySerializer уже написал?

Если ты о BinaryFormatter то в моем тесте он был быстрее всего на 12% (однородная иерархическая структура произвольной вложенности). Но ведь XmlSerializer нужно еще и xml парсить!
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 17:55
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Ремоутинг без этого жить не может


VD>Чуш. Ему нужно чтобы объект сериализовался, а как по большему счету его не трогает.


Вот не знаешь — лучше не спорь. Как ты думаешь для чего нужен интерфейс IRemotingFormatter?

VD>И вообще меня никто и никога не сможет убедить, что разница в скорости в два порядка может быть хоть чем-то аргументирована. Единственное объяснение — это бездарные алгоритмы.


Вот когда ты реализуешь настоящий форматтер — универсальный и работающий в ремоутинге и он будет хотя бы на порядок быстрее стандартного то я признаю что ты прав.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[7]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 19:02
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вот когда ты реализуешь настоящий форматтер — универсальный и работающий в ремоутинге и он будет хотя бы на порядок быстрее стандартного то я признаю что ты прав.


А зачем делать форматер? Я о том, что любой сложный объект можно записать в стрим и сделать вид, что он просто. Хотя и это тоже наверно можно.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 19:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А зачем делать форматер? Я о том, что любой сложный объект можно записать в стрим и сделать вид, что он просто.


Дык с этим вроде никто и не спорил.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[10]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 19:32
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


VD>>Дык XmlSerializer в два раза медленее чем BinarySrrializer.


AVK>То есть ты BinarySerializer уже написал?


Ты бы посмотрел тесты. Там стандартные меряются.

AVK>Если ты о BinaryFormatter то в моем тесте он был быстрее всего на 12% (однородная иерархическая структура произвольной вложенности). Но ведь XmlSerializer нужно еще и xml парсить!


XmlSerializer    - 2 734
BinaryFormatter  - 1 752
SoapFormatter    - 4 817


Я бы не назвал разницу на секунду при менее чем трех секундах двенадцатью процентами.

Если же учесть, что на такую и 1.7 секунды слишком много (минимум на порядок)...
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 19:35
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


VD>>А зачем делать форматер? Я о том, что любой сложный объект можно записать в стрим и сделать вид, что он просто.


AVK>Дык с этим вроде никто и не спорил.


Ты видимо все же не понял до конца.

Я имею в виду что можно релазовать итерфейс ЯСереализуемый в котором наплевав на советы мс банально серилизовать один поток под одним именем.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 20:22
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Если ты о BinaryFormatter то в моем тесте он был быстрее всего на 12% (однородная иерархическая структура произвольной вложенности). Но ведь XmlSerializer нужно еще и xml парсить!


VD>
VD>XmlSerializer    - 2 734
VD>BinaryFormatter  - 1 752
VD>SoapFormatter    - 4 817
VD>


VD>Я бы не назвал разницу на секунду при менее чем трех секундах двенадцатью процентами.


Результаты своих тестов я приводил, могу повторить

Total 100 iterations ...
Simple xml parsing : 15993ms (чтение при помощи XmlTextReader и полностью ручная десериализация, по сути теоретический предел для десериализации из xml на дотнете)
Simple xml parsing into DOМ : 20019ms (просто загрузка документа из xml DOM парсером) (1.6М (220К упак.) семпл)
Parsing with XmlSerializer : 19538ms (полностью автоматическая десериализация XmlSerializer) (1.6М (220К упак.) семпл)
Parsing with BinaryFormatter : 19157ms (полностью автоматическая десериализация BinaryFormatter) (800К (340К упак.) семпл)
Parsing with BinaryFormatter with custom serialization : 39517ms (А вот здесь я реализовал ISerializable, вот так вот (а полей там всего два + подчиненная коллекция)) (1.05М (380К упак.) семпл)
Parsing with XmlSerializer : 20800ms (здесь полуавтоматическиая десериализация XmlSerialize, реализован IXmlSerializable) (2.0М (220К упак.)семпл)


В чем причина отличия от твоих тестов? Видимо в том что у тебя структура слишком линейна и примитивна. В моих тестах использовалось дерево с довольно глубокой степенью вложенности хаотической структуры.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[12]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 12.04.03 20:54
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>В чем причина отличия от твоих тестов? Видимо в том что у тебя структура слишком линейна и примитивна. В моих тестах использовалось дерево с довольно глубокой степенью вложенности хаотической структуры.


Да разница только в том, что у тебя BinaryFormatter показал еще более плохую производительность. Код я товой не пробовал. (кстати, кинь я погляжу).

Кастом сериализация у тебя тормозит по вполне понятным причинам. Она сделана в лучших тардиции МС. Ты каждое поле по отдельности добавлял. Соап-форматер ты не пробовал. Почти уверен, что он минимум вдвое медленнее будет.

Ну, и гавное... ты так и не сделал реальной бинарной сериализации. Я тебе уже сказал. Она будет занимать 1-3 секунды.

Мой тест действительно оказался более лаяльным для BinaryFormatter-я. Я сам немного удивился. Но общей картины это не меняет. Ужасные тормаза! Причем, главное, что они видны в ремоутинге и вебсервисах. Вот о чем я... собственно.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 12.04.03 21:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да разница только в том, что у тебя BinaryFormatter показал еще более плохую производительность. Код я товой не пробовал. (кстати, кинь я погляжу).


Ушло мылом

VD>Кастом сериализация у тебя тормозит по вполне понятным причинам. Она сделана в лучших тардиции МС. Ты каждое поле по отдельности добавлял.


Там их всего два.

VD> Соап-форматер ты не пробовал. Почти уверен, что он минимум вдвое медленнее будет.


Меня это мало интересовало, тест немножко не для этого делался, как ты помнишь.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[13]: Сериализация в дотнете
От: mihailik Украина  
Дата: 14.04.03 13:17
Оценка:
IT>>> просто вырубил /clr

VD>>А оно надо? Скорость нормальна. Все работает...


AVK>Оно не будет верифицироваться. Если янус пустить не под админом то загрузить эту сборку в другой домен не получиться.


Насколько я понимаю, этим управляют политики. Следовательно, просто при инсталяции внести куда следует, чтобы не верифицировалось.
... << RSDN@Home 1.0 beta 6a >>
Re[3]: Сериализация в дотнете
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 14.04.03 13:27
Оценка:
Здравствуйте, VladD2, Вы писали:

DG>>1. смену версий классов (добавление, удаление полей)


VD>Попробуй бинарным форматером считать данные записанные другой версией.


вот такой класс сохраняется и load-ится со всеми добавлениями/удалениями полей
        [Serializable]
    public class Root:
        ISerializable
    {
        public Root()
        {
        }

        public Root (SerializationInfo info, StreamingContext context) 
        {
            Type type = this.GetType();
            foreach (SerializationEntry entry in info)
            {
                FieldInfo field = type.GetField(entry.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                if (field != null)
                    field.SetValue(this, entry.Value);
            }
        }
        public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            Type type = this.GetType();
            foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (!field.IsNotSerialized)
                    info.AddValue(field.Name, field.GetValue(this));
            }
        }
}
... << RSDN@Home 1.0 beta 6 >>
Re[14]: Сериализация в дотнете
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.04.03 17:54
Оценка:
Здравствуйте, mihailik, Вы писали:

AVK>>Оно не будет верифицироваться. Если янус пустить не под админом то загрузить эту сборку в другой домен не получиться.


M>Насколько я понимаю, этим управляют политики. Следовательно, просто при инсталяции внести куда следует, чтобы не верифицировалось.


Они там наверное не зря такие сделаны.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[4]: Сериализация в дотнете
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.04.03 22:32
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>вот такой класс сохраняется и load-ится со всеми добавлениями/удалениями полей


По-твоему вручную его не удастя сериализовать?

Или 60-кратные тормоза на прмитивных объектах можно этим объяснить?
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 15.04.03 05:22
Оценка: 30 (1)
Вообщем по совету Влада решил написать самопальный сериализатор датасета, функционал его выполнен не полностью (не хватает связей между таблицами,ключевых полей и может еще чего...),но для большинства случаев он сгодится, в том числе для перого Janus'а. На чистоту кода я не расчитавою, т.к. это было написано за 1-2 часа... так что высказывайте свои претензии, конечные результаты я думаю дадут максимум прирост показателей в 2 раза...

Вот результаты
DataSetHandsSerializate serialization time elapsed:  63, Length is: 147 846
BinaryFormatter serialization time elapsed:  2 843, Length is: 1 306 610
XmlSerializer serialization time elapsed:  5 250, Length is: 1 666 490
SoapFormatter serialization time elapsed:  3 641, Length is: 3 334 068


DataSetHandsSerializate стоит первым из-за того что если первым будет стоять например XmlSerializer он покажет результат по времени на секунду больше...

код

using System;
using System.Data;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

namespace TestSerialize
{

    class DataSetHandsSerializate
    {
        public static void Serialize( Stream stream, DataSet ds)
        {
            BinaryWriter bw = new BinaryWriter(stream);
            //dataset name
            bw.Write(ds.DataSetName);
            //count tables
            bw.Write(ds.Tables.Count);
            foreach (DataTable dt in ds.Tables)
            {    
                //table name
                bw.Write(dt.TableName);
                //count columns
                bw.Write(dt.Columns.Count);
                foreach (DataColumn dc in dt.Columns)
                {
                    //column name
                    bw.Write(dc.ColumnName);
                    //column type
                    bw.Write(dc.DataType.ToString());
                }

                //add data
                //count rows
                bw.Write(dt.Rows.Count);
                foreach (DataRow dr in dt.Rows)
                {
                    for (int i=0;i<dt.Columns.Count;i++)
                    {
                        //data
                        bw.Write(dr[i].ToString());
                    }

                }

            }
        }

        public static DataSet Deserialize( Stream stream )
        {
            DataSet ds = new DataSet();
            BinaryReader br = new BinaryReader(stream);
            ds.DataSetName = br.ReadString();
            int counTables = br.ReadInt32();
            DataTable dt;
            DataColumn dc;
            DataRow dr;
            for (int t=0;t<counTables;t++)
            {
                dt = new DataTable(br.ReadString());
                int counColums = br.ReadInt32();
                for (int c=0;c<counColums;c++)
                {
                    string colName = br.ReadString();
                    string sType = br.ReadString();
                    System.Type type = Type.GetType(sType);
                    dc = new DataColumn(colName,type);
                    dt.Columns.Add(dc);
                }

                int counRows = br.ReadInt32();
                for (int i=0;i<counRows;i++)
                {
                    //data
                    dr = dt.NewRow();
                    for (int c=0;c<counColums;c++)
                    {
                        string data = br.ReadString();            
                        dr[c] = String2Type( dt.Columns[c].DataType, data);
                        
                    }
                    dt.Rows.Add(dr);
                }

                ds.Tables.Add(dt);
            }
            return ds;
        }

        private static object String2Type( Type type,string data)
        {
            switch (type.ToString())
            {
                case "System.Boolean":
                    return Convert.ToBoolean(data);
                case "System.Byte":
                    return Convert.ToByte(data);
                case "System.Char":
                    return Convert.ToChar(data);
                case "System.DateTime":
                    return Convert.ToDateTime(data);
                case "System.Decimal":
                    return Convert.ToDecimal(data);
                case "System.Double":
                    return Convert.ToDouble(data);
                case "System.Int16":
                    return Convert.ToInt16(data);
                case "System.Int32":
                    return Convert.ToInt32(data);
                case "System.Int64":
                    return Convert.ToInt64(data);
                case "System.SByte":
                    return Convert.ToSByte(data);
                case "System.Single":
                    return Convert.ToSingle(data);
                case "System.String":
                    return Convert.ToString(data);
                case "System.UInt16":
                    return Convert.ToUInt16(data);
                case "System.UInt32":
                    return Convert.ToUInt32(data);
                case "System.UInt64":
                    return Convert.ToUInt64(data);
                
            }
            return null;
        }
    }
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {

            int start; // Используется для вычисления времени выполнения

            DataSet ds = new DataSet("myDataSet");
            DataTable dt = new DataTable("Table1");
            DataColumn dc1 = new DataColumn("col1", System.Type.GetType("System.Int32"));
            DataColumn dc2 = new DataColumn("col2", System.Type.GetType("System.String"));
            dt.Columns.Add(dc1);
            dt.Columns.Add(dc2);

            DataRow dr;

            for (int i=0;i<10000;i++)
            {
                dr = dt.NewRow();
                dr["col1"] = i;
                dr["col2"] = "2test"+i.ToString();
                dt.Rows.Add(dr);        
            }

            ds.Tables.Add(dt);


            // Стрим для сериализации через BinaryFormatter
            MemoryStream msBf = new MemoryStream();
            // Стрим для ручной сериализации.
            MemoryStream msBm = new MemoryStream();
            // Стрим для сериализации через SoapFormatter
            MemoryStream msSf = new MemoryStream();
            // Стрим для сериализации через XmlSerializer
            MemoryStream msXml = new MemoryStream();


            
            BinaryFormatter bf = new BinaryFormatter();
            SoapFormatter sf = new SoapFormatter();


            start = Environment.TickCount;
            DataSetHandsSerializate.Serialize(msBm, ds);
            Console.WriteLine(
                "DataSetHandsSerializate serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start,msBm.Length);

            start = Environment.TickCount;
            bf.Serialize(msBf, ds);
            Console.WriteLine(
                "BinaryFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start,msBf.Length);

            start = Environment.TickCount;
            XmlSerializer serializer = 
                new XmlSerializer(typeof(DataSet));
            serializer.Serialize(msXml, ds);
            Console.WriteLine(
                "XmlSerializer serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start,msXml.Length);

            start = Environment.TickCount;
            sf.Serialize(msBf, ds);
            Console.WriteLine(
                "SoapFormatter serialization time elapsed: {0:### ### ###}, "
                + "Length is: {1:### ### ###}",
                Environment.TickCount - start,msBf.Length);

            
            Console.ReadLine();
        }
    }
}
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[2]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 15.04.03 05:29
Оценка:
Здравствуйте, Trantor, Вы писали:

Упс, одна ошибка в тесте, не тот стрим указал для SoapFormatter, поэтому изменена длинна полученного стрима для Soap!!!

T>Вот результаты

T>
T>DataSetHandsSerializate serialization time elapsed:  63, Length is: 147 846
T>BinaryFormatter serialization time elapsed:  2 843, Length is: 1 306 610
T>XmlSerializer serialization time elapsed:  5 250, Length is: 1 666 490
T>SoapFormatter serialization time elapsed:  3 641, Length is: 2 027 458
T>
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[15]: Сериализация в дотнете
От: mihailik Украина  
Дата: 15.04.03 10:48
Оценка:
AVK>>>Оно не будет верифицироваться. Если янус пустить не под админом то загрузить эту сборку в другой домен не получиться.

M>>Насколько я понимаю, этим управляют политики. Следовательно, просто при инсталяции внести куда следует, чтобы не верифицировалось.


AVK>Они там наверное не зря такие сделаны.


Не зря, ясное дело. Беспокоятся о безопасности.

Но ты-то за свою лично программу можешь отвечать. Насколько я знаю, в политиках можно указать конкретные настройки для конкретной assembly по полному имени. Подписывайте assembly и будет всё гарантировано чисто.
... << RSDN@Home 1.0 beta 6a >>
Re[2]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.04.03 22:08
Оценка:
Здравствуйте, Trantor, Вы писали:

T>DataSetHandsSerializate стоит первым из-за того что если первым будет стоять например XmlSerializer он покажет результат по времени на секунду больше...


Поузу пробовал ставить. Ну, Sleep(300)...

T>
T>                //add data
T>                //count rows
T>                bw.Write(dt.Rows.Count);
T>                foreach (DataRow dr in dt.Rows)
T>                {
T>                    for (int i=0;i<dt.Columns.Count;i++)
T>                    {
T>                        //data
T>                        bw.Write(dr[i].ToString());
T>                    }

T>                }


А зачем же в строку?! Пиши бирари. Мы потом это дело еще зипом офигачим и через DIME таскать будем. Получится еще компактнее. Тогда не в 2, раза разница будет. И даже не в 10.


На счет DIME...

Вот как можно это сделать. На сервере:
[WebMethod]
public void GetDataSet()
{
    SoapContext sc = HttpSoapContext.ResponseContext;
    if (null == sc)
        throw new ApplicationException("Only SOAP requests allowed");

    SqlConnection conn = new SqlConnection(
        @"data source=MyServer;initial catalog=Northwind;integrated security=SSPI");

    SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM customers", conn);
    DataSet ds = new DataSet("CustomerDS");
    da.Fill(ds, "Customers");
    
    conn.Close();

    MemoryStream ms = new MemoryStream(1000000);

    DataSetHandsSerializate.Serialize(ms, ds);

    byte[] aryZip = ZipBase.Compress(ms.ToArray(), leve);
    ms.Seek(0, SeekOrigin.Begin);

    DimeAttachment dimeAttachment = new DimeAttachment("application/x-zip",
        TypeFormatEnum.MediaType, ms);

    sc.Attachments.Add(dimeAttachment);
}


А на клиенте нечто вроде:

localhost.Service1 svc = new localhost.Service1();
svc.GetDataSet();
SoapContext sc = svc.ResponseSoapContext;
MemoryStream msSrc = new MemoryStream(1000000);
ZipBase.Uncompress(sc.Attachments[0].Stream.ToArray(), msSrc);
DataSet ds = DataSetHandsSerializate.Deserialize(msSrc);
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Сериализация в дотнете (самопальный датасет)
От: ForestLabs Россия  
Дата: 16.04.03 04:10
Оценка: 6 (1)
Здравствуйте, VladD2, Вы писали:

Почти тоже самое у нас до сих пор работает в 3х-уровневой системе. (Component Services)
Основано на том, что ADOшный Recordset поддерживает IPersistStream.
Просто хватаем поток у отключенного Recordset, пакуем его с помощью ZLib,
гоним на клиента в виде потока байт, там распаковываем и — вуаля!
На клиенте отключенные Recorset, который при передаче упаковался на порядок, а то и
более.
Нечто подобное хотелось бы сваять и в этой архитектуре....

С уважением, ForestLabs.


VD>Вот как можно это сделать. На сервере:

VD>
VD>[WebMethod]
VD>public void GetDataSet()
VD>{
VD>    SoapContext sc = HttpSoapContext.ResponseContext;
VD>    if (null == sc)
VD>        throw new ApplicationException("Only SOAP requests allowed");

VD>    SqlConnection conn = new SqlConnection(
VD>        @"data source=MyServer;initial catalog=Northwind;integrated security=SSPI");

VD>    SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM customers", conn);
VD>    DataSet ds = new DataSet("CustomerDS");
VD>    da.Fill(ds, "Customers");
    
VD>    conn.Close();

VD>    MemoryStream ms = new MemoryStream(1000000);

VD>    DataSetHandsSerializate.Serialize(ms, ds);

VD>    byte[] aryZip = ZipBase.Compress(ms.ToArray(), leve);
VD>    ms.Seek(0, SeekOrigin.Begin);

VD>    DimeAttachment dimeAttachment = new DimeAttachment("application/x-zip",
VD>        TypeFormatEnum.MediaType, ms);

VD>    sc.Attachments.Add(dimeAttachment);
VD>}
VD>


VD>А на клиенте нечто вроде:


VD>
VD>localhost.Service1 svc = new localhost.Service1();
VD>svc.GetDataSet();
VD>SoapContext sc = svc.ResponseSoapContext;
VD>MemoryStream msSrc = new MemoryStream(1000000);
VD>ZipBase.Uncompress(sc.Attachments[0].Stream.ToArray(), msSrc);
VD>DataSet ds = DataSetHandsSerializate.Deserialize(msSrc);
VD>
Re[3]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 16.04.03 05:49
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Поузу пробовал ставить. Ну, Sleep(300)...


Пробывал, один фиг первый форматер, приблизительно на секунду работает больше чем если бы он был на 2,3 и т.д. месте. Видимо происходит какоето кеширование. Ручной сериализации все равно на каком месте она стоит.

VD>А зачем же в строку?! Пиши бирари.


Вот тут не совсем понятно, если колонка имеет тип string, то ты её предлагаешь в byte[] пергонять? Я что-то в этом смысла не вижу... С int и им подобными в принципе понятно, т.к. BinaryWriter понимает их, вот тока типы могут быть в DateTable Int16,Int32,Int64 а BinaryWriter сохраняет их как int(Int32), как-бы орезания потом не вышло... Я думаю т.к. мы их потом зиповать собираемся, то string и так не плохо зазипуется.

VD>Вот как можно это сделать. На сервере:


skip

Это надо дергать когото из RSDN'щиков у кого доступ к сервису есть.
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[3]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 16.04.03 06:15
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А зачем же в строку?! Пиши бирари.


решил провести небольшой эксперимет, заменил bw.Write( dr[i].ToString()) на

if (dt.Columns[i].DataType.ToString() == "System.Int32")
 bw.Write( (System.Int32)dr[i]);
else
 bw.Write( dr[i].ToString());


чтоб посмореть выигрыш хотяб для чисел, результаты время сериализации увеличилось в 2-2,5 раза, размер уменьшился на 3%. Собственно с размером: при записи значения типа Int как Int, всегда тратится 4 байта, а при записи Int как String все зависит от разрядности числа, отсюда вывод что на реальных данных это может дать как выигрыш, так и проигрыш... а вот время увеличилось...
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[4]: Сериализация в дотнете (самопальный датасет)
От: mihailik Украина  
Дата: 16.04.03 11:25
Оценка: 4 (1)
T>
T>if (dt.Columns[i].DataType.ToString() == "System.Int32")
T>


Каменный век!

if (dt.Columns[i].DataType==typeof(int))
... << RSDN@Home 1.0 beta 6a >>
Re[5]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 16.04.03 11:49
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Каменный век!


M>
M>if (dt.Columns[i].DataType==typeof(int))
M>


заклинило меня что-то, давно к NET не подходил... в принципе время стало одинаковым, но вот даст ли сохранение числовых типов в бинари, всегда выигрыш по объему: ВОПРОС
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[6]: Сериализация в дотнете (самопальный датасет)
От: mihailik Украина  
Дата: 16.04.03 12:06
Оценка:
T> в принципе время стало одинаковым, но вот даст ли сохранение числовых типов в бинари, всегда выигрыш по объему: ВОПРОС

Это как? Какой же это вопрос?

0..9 запнимает один байт в UTF8.
10..99 и -1..-9 — два байта.
100..999 и -11..-99 — три байта.
и так далее

А int32 — всегда четыре байта.

Кстати, короткие целые пишутся соответственно своей длине. Например так можно проверить:

byte i8=0xff;
ushort i16=0;
uint i32=0xffffffff;
ulong i64=0;

wr.Write(i8);
wr.Write(i16);
wr.Write(i32);
wr.Write(i64);


А потом посмотреть файл в шестнадцатеричном виде.
... << RSDN@Home 1.0 beta 6a >>
Re[3]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 12:34
Оценка:
Здравствуйте, VladD2, Вы писали:

Имхо проще зип вставить в сериалайзер
... << RSDN@Home 1.0 beta 6a >>
AVK Blog
Re[4]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 12:34
Оценка: 10 (1)
Здравствуйте, Trantor, Вы писали:


T>Пробывал, один фиг первый форматер, приблизительно на секунду работает больше чем если бы он был на 2,3 и т.д. месте. Видимо происходит какоето кеширование. Ручной сериализации все равно на каком месте она стоит.


Блин, ну сколько можно рассказывать. Вставляйте после каждого теста GC.Collect()
... << RSDN@Home 1.0 beta 6a >>
AVK Blog
Re[4]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, Trantor, Вы писали:

T>Вот тут не совсем понятно, если колонка имеет тип string, то ты её предлагаешь в byte[] пергонять?



Ну, в бинарном стриме все в байтах. Строку нужно просто писать в поток и не думать. Все само превратится. У БинариРайтера есть метод для записи строки (да ты им и пользуешся).

T>С int и им подобными в принципе понятно, т.к. BinaryWriter понимает их, вот тока типы могут быть в DateTable Int16,Int32,Int64 а BinaryWriter сохраняет их как int(Int32),


Это еще почему? У BinaryWriter есть перегнуженные методы для записи: byte (Int8), short(Int16) int(Int32), long(Int64) и их бесзнаковых аналогов. Так что все пучечком.

T>как-бы орезания потом не вышло...


Ну, мы же не мусульмане.

T>Я думаю т.к. мы их потом зиповать собираемся, то string и так не плохо зазипуется.


1. Бинарные данные быстрее читать и писать.
2. Чем меньше исходные данные, тем быстрее будет происходить сжатие.
3. Чем меньше исходные данные, тем больше они сожмутся (в абсолютных вилечинах).

T>Это надо дергать когото из RSDN'щиков у кого доступ к сервису есть.


АВК.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Блин, ну сколько можно рассказывать. Вставляйте после каждого теста GC.Collect()


Там еще нужно здать завершения сборки мусора.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Имхо проще зип вставить в сериалайзер


Да можно сделать одну функцию. На входе датасет, а не выходе зипованный стрим.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, Trantor, Вы писали:

T>
T>if (dt.Columns[i].DataType.ToString() == "System.Int32")
T> bw.Write( (System.Int32)dr[i]);
T>else
T> bw.Write( dr[i].ToString());
T>


Не, ну за такой код руки нужно подтачивать. Зачем же каждый раз столько лишних действий? Они время и сжирают.

if (types[i] == MyTypess.Int32)
  bw.Write((System.Int32)dr[i]);
else
  bw.Write( dr[i].ToString());


Нип нужно в самом начале превращать в целочисленный ID. Запихивать их в массив и потом:

T>чтоб посмореть выигрыш хотяб для чисел, результаты время сериализации увеличилось в 2-2,5 раза, размер уменьшился на 3%.


Сделай так и померяй еще раз.

T>Собственно с размером: при записи значения типа Int как Int, всегда тратится 4 байта, а при записи Int как String все зависит от разрядности числа, отсюда вывод что на реальных данных это может дать как выигрыш, так и проигрыш... а вот время увеличилось...


Вот это и нужно еще раз проверить.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Каменный век!


Согласен.

M>
M>if (dt.Columns[i].DataType==typeof(int))
M>


Но этот код тоже далек от оптимальности.

1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.
2. Каждая точка и пара скобок являются кучей лишнего кода. (dt.Columns[i].DataType[b])

Лучше все это дело сложить в массив (оптимально int-ов) и проверять уже его (см. постинг рядом).
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, Trantor, Вы писали:

T> заклинило меня что-то, давно к NET не подходил... в принципе время стало одинаковым,


Сделай что я говорю и скорее всего время уще улучшится.

T>но вот даст ли сохранение числовых типов в бинари, всегда выигрыш по объему: ВОПРОС


Типы типа дат в строках выглядят совсем погано.

Но нужно эксперементировать. Нужно пожать это дело зипом и поглядеть результат. (как по скорости сжатия, так и по объему).
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 14:51
Оценка:
Здравствуйте, ForestLabs, Вы писали:

О том и речь.

Только оверквоть по меньше.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Сериализация в дотнете (самопальный датасет)
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 16.04.03 15:19
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


Это не функция, а загрузка константы через ldtoken.
Re[6]: Сериализация в дотнете (самопальный датасет)
От: mihailik Украина  
Дата: 16.04.03 15:32
Оценка:
M>>
M>>if (dt.Columns[i].DataType==typeof(int))
M>>


VD>Но этот код тоже далек от оптимальности.


VD>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


typeof(int) — не функция. Это ссылка на метаданные, просто token. Эффект — тот же, что и у константы.


VD>2. Каждая точка и пара скобок являются кучей лишнего кода. (dt.Columns[i].DataType)



Внешние скобки — это синтаксис оператора if.

VD>Лучше все это дело сложить в массив (оптимально int-ов) и проверять уже его (см. постинг рядом).


Глупость какая-то. Давай тогда и к массиву применим твой "пункт 2". Из него тоже всё в массив выгрузим, "и проверять уже его"
... << RSDN@Home 1.0 beta 6a >>
Re[5]: Сериализация в дотнете (самопальный датасет)
От: mihailik Украина  
Дата: 16.04.03 15:34
Оценка:
VD>
VD>if (types[i] == MyTypess.Int32)
VD>  bw.Write((System.Int32)dr[i]);
VD>else
VD>  bw.Write( dr[i].ToString());
VD>


VD>Нип нужно в самом начале превращать в целочисленный ID. Запихивать их в массив и потом:


Да, правильно!
Беру свои слова обратно, types[i] стоит построить. MyTypes.Int32 всё-таки заменить на typeof(int).
... << RSDN@Home 1.0 beta 6a >>
Re[6]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 18:03
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Блин, ну сколько можно рассказывать. Вставляйте после каждого теста GC.Collect()


VD>Там еще нужно здать завершения сборки мусора.


Чего? Сборка мусора синхронна и останавливает все потоки.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[5]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 18:03
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Имхо проще зип вставить в сериалайзер


VD>Да можно сделать одну функцию. На входе датасет, а не выходе зипованный стрим.


А еще лучче ченнел синк пакующий.
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 19:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


Это оператор
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:32
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>А еще лучче ченнел синк пакующий.


Не не лучше. От тормозов это не избавит. Я тебе уже кажется наглядно продемонстрировал, что основные тормоза от форматера.

Так фоматер просто ничего не будет делать (все пойдет мимо него). А с черелом будет полная задница. Весь геморой с сериализацией датасета + все пойдет в текстовм виде. А так все пойдет через DIME.

Есть правда вариант... Форматеры поддерживают такую фичу как System.Runtime.Remoting.Messaging.RemotingSurrogateSelector.

Я так понимаю, возможно с его помощью можно будет делать "правильную" сериализацию автоматом.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:36
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Чего? Сборка мусора синхронна и останавливает все потоки.


Гы-гы.

GC.Collect() — это не сборка мусора, а только ее запуст. Как я понимаю сборка производится из потока с меньшим приоритетом и она просто будет спать если ее не подождать.

Если хочешь дождаться окончани (а видимо, и начала) сборки нужно вызывать:

  GC.Collect();
  GC.WaitForPendingFinalizers();
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.04.03 19:39
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>А еще лучче ченнел синк пакующий.


VD>Не не лучше. От тормозов это не избавит. Я тебе уже кажется наглядно продемонстрировал, что основные тормоза от форматера.


Я ж не говорю что это нужно взамен сериалайзера, я предлагаю это как способ подключения паковщика.

VD>Так фоматер просто ничего не будет делать (все пойдет мимо него). А с черелом будет полная задница. Весь геморой с сериализацией датасета + все пойдет в текстовм виде. А так все пойдет через DIME.


Форматтер это тоже синк в канале.

VD>Есть правда вариант... Форматеры поддерживают такую фичу как System.Runtime.Remoting.Messaging.RemotingSurrogateSelector.


VD>Я так понимаю, возможно с его помощью можно будет делать "правильную" сериализацию автоматом.


Можно. Этой фишкой пользуются, когда подменяют MBR на ObjRef
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[6]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:46
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Да, правильно!

M>Беру свои слова обратно, types[i] стоит построить. MyTypes.Int32 всё-таки заменить на typeof(int).

typeof(int) возвращает объект. Причем кажды раз! Сравнение объектных ссылок само по себе менее эффективно чем интов (из-за того что это приводит к виртуальным вызовам), так к тому же еще typeof() — это вызов серьезной функции.

На С++ такое влет прокатило бы (из-за оптимизации и более низкоуровневой технологии сравнения ссылок). А на Шарпе точно нужно делать отдельный массив.

В общем попробуй и замерь.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:46
Оценка: 3 (1)
Здравствуйте, AndrewVK, Вы писали:

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


VD>>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


AVK>Это оператор


Хрен. Глянь анакриной/илдасмом. Да и просто замерь скорость. Я тут как-то из твоего лихого примера (загрузки сборок, если не ошибаюсь) вынес typeof(...) за пределы цикла и получил серьезный выигрыш.

Вот это:
Type t = typeof(int);


Навно вот этому:
  .locals init (class [mscorlib]System.Type V_0)
  IL_0000:  ldtoken    [mscorlib]System.Int32
  IL_0005:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
  IL_000a:  stloc.0


Так что не делайте глупостей. Если это можно в критических местах не лепите typeof()
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:53
Оценка:
Здравствуйте, mihailik, Вы писали:

M>typeof(int) — не функция. Это ссылка на метаданные, просто token.


Гы-гы. См. http://www.rsdn.ru/forum/Message.aspx?mid=244339&amp;only=1
Автор: VladD2
Дата: 16.04.03


M>Эффект — тот же, что и у константы.


Ню-ню. Создай тестовое приложение и попробуй.

Type — это уже само по себе тяжелый объект. Он является оберткой над метаданными. Метаданные в дотнете — это не константы. Это огромные динамические структуры информация о которых хранится в сборках. Даже приметивы описаны в сборке (если не ошибаюсь в mscoree.lib). Так что сначала в стек закладывается токен (действительно констатна), а затем вызывается относительно навароченная функция которая по нему ищет объект типа Type.

VD>>2. Каждая точка и пара скобок являются кучей лишнего кода. (dt.Columns[i].DataType)


M>

M>Внешние скобки — это синтаксис оператора if.

Я имел в виду квадратные скобки.

VD>>Лучше все это дело сложить в массив (оптимально int-ов) и проверять уже его (см. постинг рядом).


M>Глупость какая-то. Давай тогда и к массиву применим твой "пункт 2". Из него тоже всё в массив выгрузим, "и проверять уже его"


Короче, попробуй... А глупость... наверно... для тех кто не понимает сути происходящего. Я видимо слишком долго писал на С и привык оценивать код с точки зрения того что он порождает на самом деле.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 19:54
Оценка:
Здравствуйте, desperado_gmbh, Вы писали:

VD>>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


DG>Это не функция, а загрузка константы через ldtoken.


Я уже тут малость задалбался отвечать. См. http://www.rsdn.ru/forum/Message.aspx?mid=244344&amp;only=1
Автор: VladD2
Дата: 16.04.03
и http://www.rsdn.ru/forum/Message.aspx?mid=244339&amp;only=1
Автор: VladD2
Дата: 16.04.03
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.04.03 20:06
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Я ж не говорю что это нужно взамен сериалайзера, я предлагаю это как способ подключения паковщика.


А. Ну, это разумно. Вот только может оказаться проблематично передавать бинарные данные по http. Я ведь говорил о передачи в виде DIME-атача. Хотя если знать формат DIME, можно наверно все данные по нему качать. Такой легкий способ борьбы с фаерволами. А в теле вызова передавать строчку "Фаерволы идут лесом (с) IT"

AVK>Форматтер это тоже синк в канале.


Тогда нужно вести речь о самопальном форматере. Но это уже не так просто.

AVK>Можно. Этой фишкой пользуются, когда подменяют MBR на ObjRef


Ладно. Сделать рукопашнену для датасета можно за час-другой уже сейчас. А с RemotingSurrogateSelector еще капать и капать.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.04.03 02:45
Оценка:
Здравствуйте, Trantor, Вы писали:

У тебя в тесте была ошибка. Ты писал данные Soap-фрматера в стрим Binary-форматера. Что увеличивало размер последнего.

Видимо из-за этого и менялись результаты при перестановках. Я переписал твой сериализатор сделав его полностью бирантым и оптимизировав те места которые мне показались наиболее требовательными к времени. Так же сделал подсчет загрузки. Результаты оказались настлько забавными что решил создать отдельную тему.

Попутно обнаружил серезный недостаток. Дело в том, что ты не расчитываешь на то, что ячейки могут содержать DbNull. Т.е. этот вариант будет работать только на датасетах без null-ов.

Вот мой вариант: http://www.rsdn.ru/forum/?mid=244451
Автор: VladD2
Дата: 17.04.03
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.04.03 02:45
Оценка:
Здравствуйте, AndrewVK, Вы писали:

VD>>1. typeof(int) = это функция которую тупой Шарповый компилятор не догадается вынести из цыкла.


AVK>Это оператор


Глянь переписаный вариант.

http://www.rsdn.ru/forum/Message.aspx?mid=244451&amp;only=1
Автор: VladD2
Дата: 17.04.03


Сравни скорость. Я так понимаю ты и на все остальные оптимизации скажешь, что это все бессмысленная трата времени. Однако эффект на лицо. Разница не на проценты, а в 3-4 раза. И это при том, что Trantor заявлял, что скорость от бинарности не увеличится.

В общем-то он прав. Основной выигрышь за счет оптимизаций типа выноса typeof(int) из цикла.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 17.04.03 05:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Типы типа дат в строках выглядят совсем погано.


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

VD>Но нужно эксперементировать. Нужно пожать это дело зипом и поглядеть результат. (как по скорости сжатия, так и по объему).


А где ксати ЗИП взять который под НЕТ ты использовал (не ActiveZIP)?
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[5]: Сериализация в дотнете (самопальный датасет)
От: Trantor Россия  
Дата: 17.04.03 05:10
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это еще почему? У BinaryWriter есть перегнуженные методы для записи: byte (Int8), short(Int16) int(Int32), long(Int64) и их бесзнаковых аналогов. Так что все пучечком.


ОК.

VD>Ну, мы же не мусульмане.




T>>Это надо дергать когото из RSDN'щиков у кого доступ к сервису есть.

VD>АВК.

АВК — дерг,дерг...
... << RSDN@Home 1.0 beta 6a >>
В жизни мало быть умным, надо еще быть не дураком.
Re[8]: Сериализация в дотнете (самопальный датасет)
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 17.04.03 09:01
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так что сначала в стек закладывается токен (действительно констатна), а затем вызывается относительно навароченная функция которая по нему ищет объект типа Type.


А ведь и правда. Если я правильно понял исходник, то GetClassFromHandle.
Re[8]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 17.04.03 20:54
Оценка:
Здравствуйте, Trantor, Вы писали:

T>А где ксати ЗИП взять который под НЕТ ты использовал (не ActiveZIP)?


Позже сделаю подборку. Пока что кидай мыло вышлю почтой. ~ 870 килобайт.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 18.04.03 05:55
Оценка:
Здравствуйте, VladD2, Вы писали:

T>>А где ксати ЗИП взять который под НЕТ ты использовал (не ActiveZIP)?


VD>Позже сделаю подборку. Пока что кидай мыло вышлю почтой. ~ 870 килобайт.


Мама миа, а чего такой огромный?
... << RSDN@Home 1.0 beta 6a >>
AVK Blog
Re[8]: Сериализация в дотнете (самопальный датасет)
От: mihailik Украина  
Дата: 18.04.03 14:39
Оценка:
VD>В общем-то он прав. Основной выигрышь за счет оптимизаций типа выноса typeof(int) из цикла.

Я проверил, написал небольшой цикл с typeof(int) и с static readonly Int32Type. Вопреки всем разумным объяснениям typeof(int) действительно медленнее!

На 2 млн циклах показатели такие:
Int32Type   0.220 с
typeof(int) 1.232 с


Это просто антинаучный факт!

На всякий случай сделал сравнение с проверкой "is int" для самого объекта. То же самое, что и typeof(int), та же скорость.

Влад, спасибо, научил.
... << RSDN@Home 1.0 beta 6a >>
Re[10]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.04.03 14:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Мама миа, а чего такой огромный?


То на что дал ссылку ты еще больше (вроде).
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.04.03 14:42
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Мама миа, а чего такой огромный?


Да. ~ 870 килобайт — это исходники. Получаемая длл 130 кил.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Сериализация в дотнете (самопальный датасет)
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 19.04.03 08:38
Оценка:
Здравствуйте, VladD2, Вы писали:

AVK>>Мама миа, а чего такой огромный?


VD>То на что дал ссылку ты еще больше (вроде).


Афигеть. На Дельфи zlib был что то вроде 50к dcu
... << RSDN@Home 1.0 beta 6a (np: тихо) >>
AVK Blog
Re[12]: Сериализация в дотнете (самопальный датасет)
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.04.03 14:09
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Афигеть. На Дельфи zlib был что то вроде 50к dcu


Какой нахнер dcu? Я об исходниках! Блин...

Если же говорить о Дельфи. То 50 кил на dcu можно добиться только используюя линковку с рантайм-сборками. При этом тебе придется еще мегабайт рантаяма таскать. А если ликоваться статически, то меньше 200 кил длл-ку не получить. Здесь же 130 кил.

Думаю что в дельфи 50 кил — это была обертка над длл-ю.
... << RSDN@Home 1.0 beta 6a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.