# KnBinarySerializer **Repository Path**: kevin2y/KnBinarySerializer ## Basic Information - **Project Name**: KnBinarySerializer - **Description**: 一个简单、高效的字节序列化工具类。支持将DataTable序列为字节数组。 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-05-02 - **Last Updated**: 2024-11-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # KnBianaySerializer #### 介绍 一个简单的字节序列化工具类。速度快,占用字节少。 #### 软件架构 实现特定类型的IFormatter就可处理不同类型的对象。现在支持class\Diction<,>\List<>。 与[RRQMSocket](https://gitee.com/dotnetchina/RRQMSocket)的比较中,在速度与空间利用上都要小胜。 与[KGySoft.CoreLibraries](https://github.com/koszeggy/KGySoft.CoreLibraries)的比较,本组件速度更快,空间节省一半,特别是DataTable #### 使用说明 1. 引用项目,或将生成的dll引用到您的项目中 2. 序列化DataTable ``` DataTable table = buildDictTable(); byte[] buffer = KnBinarySerializer.BianaySerializer.Serialize(table); var compare = KnBinarySerializer.BianaySerializer.DeSerialize(buffer); ``` 3. 序列化对象 ``` MyClass myClass = new MyClass(); myClass.Id = 1; myClass.Age = 20; myClass.Name = "kevin"; myClass.Birthday = DateTime.Now.AddYears(-2); myClass.Depart = new Depart(1, "总部"); myClass.MyTable = buildDictTable(); byte[] buffer = KnBinarySerializer.BianaySerializer.Serialize(myClass); var compare = KnBinarySerializer.BianaySerializer.DeSerialize(buffer); ``` #### 特点 1.扩展方便。现在已支持DataSet/DataTable的序列化,需要的同学可以参考一下Brick/DataTableFormatter.cs等 2.对于**特殊类型列**的DataTable也可支持。为了支持列类型Dictionary,特意在DictionayFormatter中记录key\val的类型,反序列时可以重新创建合适的列内容。 // * Summary * BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2428/22H2/2022Update/SunValley2) 12th Gen Intel Core i7-1260P, 1 CPU, 16 logical and 12 physical cores .NET SDK 7.0.400 [Host] : .NET 6.0.21 (6.0.2123.36311), X64 RyuJIT AVX2 [AttachedDebugger] DefaultJob : .NET 6.0.21 (6.0.2123.36311), X64 RyuJIT AVX2 // * Warnings * Environment Summary -> Benchmark was executed with attached debugger // * Hints * Outliers SerialTest.RunKnb1: Default -> 1 outlier was detected (17.75 us) | Method | Mean | Error | StdDev | |--------- |----------:|----------:|----------:| | RunKnb1 | 18.125 us | 0.1492 us | 0.1395 us | | RunKnb2 | 28.200 us | 0.3396 us | 0.3177 us | | RunNewt1 | 3.021 us | 0.0361 us | 0.0338 us | | RunNewt2 | 9.074 us | 0.0984 us | 0.0921 us | 增加get/set的emit方法 | Method | Mean | Error | StdDev | |--------- |----------:|----------:|----------:| | RunKnb1 | 13.444 us | 0.1419 us | 0.1327 us | | RunKnb2 | 19.444 us | 0.3793 us | 0.5317 us | | RunNewt1 | 2.955 us | 0.0328 us | 0.0274 us | | RunNewt2 | 9.129 us | 0.1823 us | 0.2433 us | 左计右计,原来初始化MemoryStream的大小对于这个对比影响这么大,调整后,小容量基本能与Newtsoft.json持平,大容量速度空间完胜 | Method | Mean | Error | StdDev | |---------------- |-----------:|---------:|---------:| | RunNewtIntList | 1,037.4 us | 20.32 us | 22.58 us | | RunKnbIntList | 397.9 us | 7.07 us | 6.61 us | #### 两个项目 KnBinarySerializer早期项目。第个写入的对象都会在头部有一个长度位(int)。如类写入完成后,框架会跳回之前记录的头部写该类的总长度。这种Position的修改不利于加入Gzip的,所以在2024年重构了一个项目KnBinSerializer。 KnBinSerializer支持Gzip。2024在早期项目的结构上,去掉了总长度的写入机制。保证顺序读/写stream.但这会生成一个问题:属性缺失问题。 #### 属性缺失问题 KnBinarySerializer早期项目不存在属性缺失问题,因其每一个写入的内容都在其头部有一个int记录长度,所以可以直接跳过任何的中间字段。 KnBinSerializer为了支持Gzip,去掉了每个内容的头部长度,所以对于类来说,有可能在属性缺失时提示:无法获取长度,请为{type.Name}补充以下字段:{fieldname}。如果{fieldname}字段为基础类型,如string、int、DateTime等,因长度固定或有写入长度,这样的字段缺失不会产生“属性缺失问题”