diff --git a/Docs/Serialization.md b/Docs/Serialization.md index 95b4bad..9c66b89 100644 --- a/Docs/Serialization.md +++ b/Docs/Serialization.md @@ -98,7 +98,7 @@ public partial struct NotAutoCollectStruct > 需要Unity2022.3及以上版本 -1. 下载[Nino.unitypackage](Nino.unitypackage) +1. 下载[Nino.unitypackage](/Nino.unitypackage) 2. 导入到Unity diff --git a/Performance/Serialization.md b/Performance/Serialization.md index 42f6be5..061964c 100644 --- a/Performance/Serialization.md +++ b/Performance/Serialization.md @@ -1,495 +1,49 @@ # Serilization 性能报告 -#### [**测试数据**](/Nino_Unity/Assets/Nino/Test/Data.cs) - -## Unity平台性能测试 - -新版数据待补充 - - - ## 非Unity平台性能测试 -#### [**测试数据**](/src/Nino.Benchmark/Serialization/Models) +#### [**测试数据**](/src/Nino.Benchmark/Data.cs) -```ini -BenchmarkDotNet=v0.13.1, OS=macOS 14.4 (23E214) [Darwin 23.4.0] +``` +BenchmarkDotNet v0.13.12, macOS Sonoma 14.4 (23E214) [Darwin 23.4.0] Apple M1, 1 CPU, 8 logical and 8 physical cores -.NET SDK=8.0.302 - [Host] : .NET 6.0.7 (6.0.722.32202), Arm64 RyuJIT - ShortRun : .NET 6.0.7 (6.0.722.32202), Arm64 RyuJIT +.NET SDK 8.0.302 + [Host] : .NET 8.0.6 (8.0.624.26715), Arm64 RyuJIT AdvSIMD + Job-QCQJSF : .NET 8.0.6 (8.0.624.26715), Arm64 RyuJIT AdvSIMD -Job=ShortRun Platform=AnyCpu Runtime=.NET 6.0 -IterationCount=1 LaunchCount=1 WarmupCount=1 +Runtime=.NET 8.0 IterationCount=10 WarmupCount=3 ``` -| Method | Serializer | Mean | Error | DataSize | Gen 0 | Gen 1 | Gen 2 | Allocated | -| --------------------------------- | ------------------- | --------------------:| ------:| ----------:| ------------:| ------------:| ------------:| -------------:| -| **_PrimitiveBoolDeserialize** | **MessagePack_Lz4** | **138.154 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveBoolDeserialize | MessagePack_NoComp | 34.835 ns | NA | - | - | - | - | - | -| _PrimitiveBoolDeserialize | ProtobufNet | 228.947 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveBoolDeserialize | JsonNet | 698.559 ns | NA | - | 2.7094 | - | - | 5,672 B | -| _PrimitiveBoolDeserialize | BinaryFormatter | 1,840.803 ns | NA | - | 1.9741 | - | - | 4,128 B | -| _PrimitiveBoolDeserialize | DataContract | 1,371.300 ns | NA | - | 1.9932 | - | - | 4,168 B | -| _PrimitiveBoolDeserialize | Jil | 67.400 ns | NA | - | 0.0612 | - | - | 128 B | -| _PrimitiveBoolDeserialize | SpanJson | 8.642 ns | NA | - | - | - | - | - | -| _PrimitiveBoolDeserialize | UTF8Json | 17.746 ns | NA | - | - | - | - | - | -| _PrimitiveBoolDeserialize | FsPickler | 436.889 ns | NA | - | 0.4897 | - | - | 1,024 B | -| _PrimitiveBoolDeserialize | Ceras | 81.393 ns | NA | - | - | - | - | - | -| _PrimitiveBoolDeserialize | Odin | 336.371 ns | NA | - | - | - | - | - | -| _PrimitiveBoolDeserialize | Nino | 6.792 ns | NA | - | - | - | - | - | -| **_PrimitiveBoolSerialize** | **MessagePack_Lz4** | **79.599 ns** | **NA** | **1 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveBoolSerialize | MessagePack_NoComp | 55.110 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| _PrimitiveBoolSerialize | ProtobufNet | 151.542 ns | NA | 2 B | 0.1798 | - | - | 376 B | -| _PrimitiveBoolSerialize | JsonNet | 357.001 ns | NA | 8 B | 1.3847 | - | - | 2,896 B | -| _PrimitiveBoolSerialize | BinaryFormatter | 1,081.531 ns | NA | 53 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveBoolSerialize | DataContract | 504.433 ns | NA | 84 B | 0.8221 | - | - | 1,720 B | -| _PrimitiveBoolSerialize | Jil | 81.348 ns | NA | 5 B | 0.0802 | - | - | 168 B | -| _PrimitiveBoolSerialize | SpanJson | 60.337 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveBoolSerialize | UTF8Json | 39.744 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveBoolSerialize | FsPickler | 384.877 ns | NA | 27 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveBoolSerialize | Ceras | 311.272 ns | NA | 1 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveBoolSerialize | Odin | 296.972 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| _PrimitiveBoolSerialize | Nino | 45.895 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| **_PrimitiveByteDeserialize** | **MessagePack_Lz4** | **140.927 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveByteDeserialize | MessagePack_NoComp | 37.846 ns | NA | - | - | - | - | - | -| _PrimitiveByteDeserialize | ProtobufNet | 237.784 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveByteDeserialize | JsonNet | 766.116 ns | NA | - | 2.7342 | - | - | 5,720 B | -| _PrimitiveByteDeserialize | BinaryFormatter | 1,879.898 ns | NA | - | 1.9703 | - | - | 4,120 B | -| _PrimitiveByteDeserialize | DataContract | 1,404.626 ns | NA | - | 1.9779 | - | - | 4,136 B | -| _PrimitiveByteDeserialize | Jil | 72.669 ns | NA | - | 0.0612 | - | - | 128 B | -| _PrimitiveByteDeserialize | SpanJson | 13.104 ns | NA | - | - | - | - | - | -| _PrimitiveByteDeserialize | UTF8Json | 22.138 ns | NA | - | - | - | - | - | -| _PrimitiveByteDeserialize | FsPickler | 397.637 ns | NA | - | 0.4859 | - | - | 1,016 B | -| _PrimitiveByteDeserialize | Ceras | 84.118 ns | NA | - | - | - | - | - | -| _PrimitiveByteDeserialize | Odin | 330.478 ns | NA | - | - | - | - | - | -| _PrimitiveByteDeserialize | Nino | 7.143 ns | NA | - | - | - | - | - | -| **_PrimitiveByteSerialize** | **MessagePack_Lz4** | **86.356 ns** | **NA** | **2 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveByteSerialize | MessagePack_NoComp | 55.695 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| _PrimitiveByteSerialize | ProtobufNet | 152.647 ns | NA | 3 B | 0.1798 | - | - | 376 B | -| _PrimitiveByteSerialize | JsonNet | 362.860 ns | NA | 6 B | 1.4305 | - | - | 2,992 B | -| _PrimitiveByteSerialize | BinaryFormatter | 1,104.899 ns | NA | 50 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveByteSerialize | DataContract | 521.876 ns | NA | 92 B | 0.8259 | - | - | 1,728 B | -| _PrimitiveByteSerialize | Jil | 94.967 ns | NA | 3 B | 0.1262 | - | - | 264 B | -| _PrimitiveByteSerialize | SpanJson | 71.482 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveByteSerialize | UTF8Json | 47.159 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveByteSerialize | FsPickler | 358.660 ns | NA | 24 B | 0.5240 | - | - | 1,096 B | -| _PrimitiveByteSerialize | Ceras | 297.265 ns | NA | 1 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveByteSerialize | Odin | 295.767 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| _PrimitiveByteSerialize | Nino | 45.686 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| **_PrimitiveCharDeserialize** | **MessagePack_Lz4** | **138.571 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveCharDeserialize | MessagePack_NoComp | 35.597 ns | NA | - | - | - | - | - | -| _PrimitiveCharDeserialize | ProtobufNet | 226.587 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveCharDeserialize | JsonNet | 741.717 ns | NA | - | 2.7342 | - | - | 5,720 B | -| _PrimitiveCharDeserialize | BinaryFormatter | 1,835.992 ns | NA | - | 1.9703 | - | - | 4,120 B | -| _PrimitiveCharDeserialize | DataContract | 1,302.357 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveCharDeserialize | Jil | 59.750 ns | NA | - | 0.0153 | - | - | 32 B | -| _PrimitiveCharDeserialize | SpanJson | 15.584 ns | NA | - | - | - | - | - | -| _PrimitiveCharDeserialize | UTF8Json | 41.326 ns | NA | - | 0.0114 | - | - | 24 B | -| _PrimitiveCharDeserialize | FsPickler | 411.508 ns | NA | - | 0.4854 | - | - | 1,016 B | -| _PrimitiveCharDeserialize | Ceras | 80.834 ns | NA | - | - | - | - | - | -| _PrimitiveCharDeserialize | Odin | 324.539 ns | NA | - | - | - | - | - | -| _PrimitiveCharDeserialize | Nino | 6.892 ns | NA | - | - | - | - | - | -| **_PrimitiveCharSerialize** | **MessagePack_Lz4** | **85.758 ns** | **NA** | **1 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveCharSerialize | MessagePack_NoComp | 69.001 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| _PrimitiveCharSerialize | ProtobufNet | 152.231 ns | NA | 2 B | 0.1798 | - | - | 376 B | -| _PrimitiveCharSerialize | JsonNet | 492.932 ns | NA | 6 B | 1.5526 | - | - | 3,248 B | -| _PrimitiveCharSerialize | BinaryFormatter | 1,103.618 ns | NA | 50 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveCharSerialize | DataContract | 510.479 ns | NA | 75 B | 0.8183 | - | - | 1,712 B | -| _PrimitiveCharSerialize | Jil | 89.164 ns | NA | 3 B | 0.0802 | - | - | 168 B | -| _PrimitiveCharSerialize | SpanJson | 69.630 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveCharSerialize | UTF8Json | 56.711 ns | NA | 3 B | 0.0268 | - | - | 56 B | -| _PrimitiveCharSerialize | FsPickler | 370.472 ns | NA | 24 B | 0.5240 | - | - | 1,096 B | -| _PrimitiveCharSerialize | Ceras | 300.466 ns | NA | 2 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveCharSerialize | Odin | 293.254 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveCharSerialize | Nino | 46.393 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| **_PrimitiveDateTimeDeserialize** | **MessagePack_Lz4** | **156.941 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveDateTimeDeserialize | MessagePack_NoComp | 48.308 ns | NA | - | - | - | - | - | -| _PrimitiveDateTimeDeserialize | ProtobufNet | 262.173 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveDateTimeDeserialize | JsonNet | 879.942 ns | NA | - | 2.7342 | - | - | 5,720 B | -| _PrimitiveDateTimeDeserialize | BinaryFormatter | 2,997.075 ns | NA | - | 2.7847 | - | - | 5,829 B | -| _PrimitiveDateTimeDeserialize | DataContract | 1,525.927 ns | NA | - | 2.0504 | - | - | 4,288 B | -| _PrimitiveDateTimeDeserialize | Jil | 173.105 ns | NA | - | 0.0801 | - | - | 168 B | -| _PrimitiveDateTimeDeserialize | SpanJson | 131.820 ns | NA | - | - | - | - | - | -| _PrimitiveDateTimeDeserialize | UTF8Json | 142.324 ns | NA | - | - | - | - | - | -| _PrimitiveDateTimeDeserialize | FsPickler | 459.902 ns | NA | - | 0.4892 | - | - | 1,024 B | -| _PrimitiveDateTimeDeserialize | Ceras | 143.418 ns | NA | - | - | - | - | - | -| _PrimitiveDateTimeDeserialize | Odin | 603.361 ns | NA | - | 0.0496 | - | - | 104 B | -| _PrimitiveDateTimeDeserialize | Nino | 6.552 ns | NA | - | - | - | - | - | -| **_PrimitiveDateTimeSerialize** | **MessagePack_Lz4** | **332.269 ns** | **NA** | **6 B** | **0.0458** | **-** | **-** | **96 B** | -| _PrimitiveDateTimeSerialize | MessagePack_NoComp | 135.973 ns | NA | 6 B | 0.0153 | - | - | 32 B | -| _PrimitiveDateTimeSerialize | ProtobufNet | 201.055 ns | NA | 6 B | 0.1798 | - | - | 376 B | -| _PrimitiveDateTimeSerialize | JsonNet | 481.834 ns | NA | 30 B | 1.4410 | - | - | 3,016 B | -| _PrimitiveDateTimeSerialize | BinaryFormatter | 1,487.415 ns | NA | 78 B | 1.7471 | - | - | 3,656 B | -| _PrimitiveDateTimeSerialize | DataContract | 733.898 ns | NA | 106 B | 1.0252 | - | - | 2,144 B | -| _PrimitiveDateTimeSerialize | Jil | 261.569 ns | NA | 22 B | 0.2027 | - | - | 424 B | -| _PrimitiveDateTimeSerialize | SpanJson | 169.704 ns | NA | 27 B | 0.0267 | - | - | 56 B | -| _PrimitiveDateTimeSerialize | UTF8Json | 179.136 ns | NA | 27 B | 0.0267 | - | - | 56 B | -| _PrimitiveDateTimeSerialize | FsPickler | 438.445 ns | NA | 44 B | 0.5355 | - | - | 1,120 B | -| _PrimitiveDateTimeSerialize | Ceras | 429.250 ns | NA | 8 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveDateTimeSerialize | Odin | 526.029 ns | NA | 99 B | 0.0610 | - | - | 128 B | -| _PrimitiveDateTimeSerialize | Nino | 52.666 ns | NA | 8 B | 0.0153 | - | - | 32 B | -| **_PrimitiveIntDeserialize** | **MessagePack_Lz4** | **149.839 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveIntDeserialize | MessagePack_NoComp | 41.892 ns | NA | - | - | - | - | - | -| _PrimitiveIntDeserialize | ProtobufNet | 266.465 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveIntDeserialize | JsonNet | 1,223.894 ns | NA | - | 2.7227 | - | - | 5,696 B | -| _PrimitiveIntDeserialize | BinaryFormatter | 1,951.010 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveIntDeserialize | DataContract | 1,382.555 ns | NA | - | 1.9779 | - | - | 4,136 B | -| _PrimitiveIntDeserialize | Jil | 90.209 ns | NA | - | 0.0688 | - | - | 144 B | -| _PrimitiveIntDeserialize | SpanJson | 33.476 ns | NA | - | - | - | - | - | -| _PrimitiveIntDeserialize | UTF8Json | 68.596 ns | NA | - | - | - | - | - | -| _PrimitiveIntDeserialize | FsPickler | 424.458 ns | NA | - | 0.4859 | - | - | 1,016 B | -| _PrimitiveIntDeserialize | Ceras | 97.100 ns | NA | - | - | - | - | - | -| _PrimitiveIntDeserialize | Odin | 436.772 ns | NA | - | - | - | - | - | -| _PrimitiveIntDeserialize | Nino | 7.357 ns | NA | - | - | - | - | - | -| **_PrimitiveIntSerialize** | **MessagePack_Lz4** | **81.509 ns** | **NA** | **5 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveIntSerialize | MessagePack_NoComp | 57.925 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveIntSerialize | ProtobufNet | 162.813 ns | NA | 11 B | 0.1836 | - | - | 384 B | -| _PrimitiveIntSerialize | JsonNet | 401.783 ns | NA | 14 B | 1.4343 | - | - | 3,000 B | -| _PrimitiveIntSerialize | BinaryFormatter | 1,107.493 ns | NA | 54 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveIntSerialize | DataContract | 547.554 ns | NA | 82 B | 0.8221 | - | - | 1,720 B | -| _PrimitiveIntSerialize | Jil | 103.493 ns | NA | 11 B | 0.1377 | - | - | 288 B | -| _PrimitiveIntSerialize | SpanJson | 74.425 ns | NA | 11 B | 0.0191 | - | - | 40 B | -| _PrimitiveIntSerialize | UTF8Json | 54.700 ns | NA | 11 B | 0.0191 | - | - | 40 B | -| _PrimitiveIntSerialize | FsPickler | 362.363 ns | NA | 28 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveIntSerialize | Ceras | 304.973 ns | NA | 5 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveIntSerialize | Odin | 300.540 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveIntSerialize | Nino | 50.565 ns | NA | 4 B | 0.0153 | - | - | 32 B | -| **_PrimitiveLongDeserialize** | **MessagePack_Lz4** | **150.910 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveLongDeserialize | MessagePack_NoComp | 47.484 ns | NA | - | - | - | - | - | -| _PrimitiveLongDeserialize | ProtobufNet | 252.726 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveLongDeserialize | JsonNet | 902.901 ns | NA | - | 2.7227 | - | - | 5,696 B | -| _PrimitiveLongDeserialize | BinaryFormatter | 2,093.677 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveLongDeserialize | DataContract | 1,432.751 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveLongDeserialize | Jil | 107.435 ns | NA | - | 0.0764 | - | - | 160 B | -| _PrimitiveLongDeserialize | SpanJson | 52.870 ns | NA | - | - | - | - | - | -| _PrimitiveLongDeserialize | UTF8Json | 42.496 ns | NA | - | - | - | - | - | -| _PrimitiveLongDeserialize | FsPickler | 409.521 ns | NA | - | 0.4859 | - | - | 1,016 B | -| _PrimitiveLongDeserialize | Ceras | 85.765 ns | NA | - | - | - | - | - | -| _PrimitiveLongDeserialize | Odin | 341.088 ns | NA | - | - | - | - | - | -| _PrimitiveLongDeserialize | Nino | 7.468 ns | NA | - | - | - | - | - | -| **_PrimitiveLongSerialize** | **MessagePack_Lz4** | **87.856 ns** | **NA** | **9 B** | **0.0497** | **-** | **-** | **104 B** | -| _PrimitiveLongSerialize | MessagePack_NoComp | 61.159 ns | NA | 9 B | 0.0191 | - | - | 40 B | -| _PrimitiveLongSerialize | ProtobufNet | 161.365 ns | NA | 10 B | 0.1836 | - | - | 384 B | -| _PrimitiveLongSerialize | JsonNet | 393.757 ns | NA | 22 B | 1.4377 | - | - | 3,008 B | -| _PrimitiveLongSerialize | BinaryFormatter | 1,110.127 ns | NA | 58 B | 1.4725 | - | - | 3,080 B | -| _PrimitiveLongSerialize | DataContract | 566.216 ns | NA | 92 B | 0.8259 | - | - | 1,728 B | -| _PrimitiveLongSerialize | Jil | 175.156 ns | NA | 19 B | 0.1988 | - | - | 416 B | -| _PrimitiveLongSerialize | SpanJson | 89.119 ns | NA | 19 B | 0.0229 | - | - | 48 B | -| _PrimitiveLongSerialize | UTF8Json | 67.362 ns | NA | 19 B | 0.0229 | - | - | 48 B | -| _PrimitiveLongSerialize | FsPickler | 368.727 ns | NA | 32 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveLongSerialize | Ceras | 297.324 ns | NA | 8 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveLongSerialize | Odin | 313.398 ns | NA | 9 B | 0.0191 | - | - | 40 B | -| _PrimitiveLongSerialize | Nino | 47.426 ns | NA | 8 B | 0.0153 | - | - | 32 B | -| **_PrimitiveSByteDeserialize** | **MessagePack_Lz4** | **173.292 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveSByteDeserialize | MessagePack_NoComp | 52.830 ns | NA | - | - | - | - | - | -| _PrimitiveSByteDeserialize | ProtobufNet | 273.530 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveSByteDeserialize | JsonNet | 956.921 ns | NA | - | 2.7332 | - | - | 5,720 B | -| _PrimitiveSByteDeserialize | BinaryFormatter | 2,406.986 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveSByteDeserialize | DataContract | 1,538.804 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveSByteDeserialize | Jil | 108.764 ns | NA | - | 0.0612 | - | - | 128 B | -| _PrimitiveSByteDeserialize | SpanJson | 19.181 ns | NA | - | - | - | - | - | -| _PrimitiveSByteDeserialize | UTF8Json | 24.775 ns | NA | - | - | - | - | - | -| _PrimitiveSByteDeserialize | FsPickler | 432.665 ns | NA | - | 0.4854 | - | - | 1,016 B | -| _PrimitiveSByteDeserialize | Ceras | 92.021 ns | NA | - | - | - | - | - | -| _PrimitiveSByteDeserialize | Odin | 350.089 ns | NA | - | - | - | - | - | -| _PrimitiveSByteDeserialize | Nino | 9.722 ns | NA | - | - | - | - | - | -| **_PrimitiveSByteSerialize** | **MessagePack_Lz4** | **87.291 ns** | **NA** | **2 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveSByteSerialize | MessagePack_NoComp | 59.358 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| _PrimitiveSByteSerialize | ProtobufNet | 168.891 ns | NA | 11 B | 0.1836 | - | - | 384 B | -| _PrimitiveSByteSerialize | JsonNet | 378.217 ns | NA | 7 B | 1.4305 | - | - | 2,992 B | -| _PrimitiveSByteSerialize | BinaryFormatter | 1,102.299 ns | NA | 51 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveSByteSerialize | DataContract | 518.520 ns | NA | 77 B | 0.8183 | - | - | 1,712 B | -| _PrimitiveSByteSerialize | Jil | 97.455 ns | NA | 4 B | 0.1262 | - | - | 264 B | -| _PrimitiveSByteSerialize | SpanJson | 78.699 ns | NA | 4 B | 0.0153 | - | - | 32 B | -| _PrimitiveSByteSerialize | UTF8Json | 43.862 ns | NA | 4 B | 0.0153 | - | - | 32 B | -| _PrimitiveSByteSerialize | FsPickler | 376.530 ns | NA | 25 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveSByteSerialize | Ceras | 318.932 ns | NA | 1 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveSByteSerialize | Odin | 298.178 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| _PrimitiveSByteSerialize | Nino | 46.545 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| **_PrimitiveShortDeserialize** | **MessagePack_Lz4** | **160.890 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveShortDeserialize | MessagePack_NoComp | 44.612 ns | NA | - | - | - | - | - | -| _PrimitiveShortDeserialize | ProtobufNet | 361.034 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveShortDeserialize | JsonNet | 1,075.247 ns | NA | - | 2.7342 | - | - | 5,720 B | -| _PrimitiveShortDeserialize | BinaryFormatter | 2,022.474 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveShortDeserialize | DataContract | 1,445.760 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveShortDeserialize | Jil | 80.609 ns | NA | - | 0.0612 | - | - | 128 B | -| _PrimitiveShortDeserialize | SpanJson | 23.109 ns | NA | - | - | - | - | - | -| _PrimitiveShortDeserialize | UTF8Json | 52.577 ns | NA | - | - | - | - | - | -| _PrimitiveShortDeserialize | FsPickler | 609.941 ns | NA | - | 0.4845 | - | - | 1,016 B | -| _PrimitiveShortDeserialize | Ceras | 86.731 ns | NA | - | - | - | - | - | -| _PrimitiveShortDeserialize | Odin | 431.929 ns | NA | - | - | - | - | - | -| _PrimitiveShortDeserialize | Nino | 7.423 ns | NA | - | - | - | - | - | -| **_PrimitiveShortSerialize** | **MessagePack_Lz4** | **84.547 ns** | **NA** | **3 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveShortSerialize | MessagePack_NoComp | 58.656 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveShortSerialize | ProtobufNet | 153.442 ns | NA | 4 B | 0.1798 | - | - | 376 B | -| _PrimitiveShortSerialize | JsonNet | 372.307 ns | NA | 8 B | 1.4305 | - | - | 2,992 B | -| _PrimitiveShortSerialize | BinaryFormatter | 1,090.255 ns | NA | 52 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveShortSerialize | DataContract | 514.747 ns | NA | 80 B | 0.8183 | - | - | 1,712 B | -| _PrimitiveShortSerialize | Jil | 102.524 ns | NA | 5 B | 0.1262 | - | - | 264 B | -| _PrimitiveShortSerialize | SpanJson | 67.962 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveShortSerialize | UTF8Json | 44.620 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveShortSerialize | FsPickler | 374.226 ns | NA | 26 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveShortSerialize | Ceras | 310.373 ns | NA | 2 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveShortSerialize | Odin | 293.746 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveShortSerialize | Nino | 48.027 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| **_PrimitiveStringDeserialize** | **MessagePack_Lz4** | **544.289 ns** | **NA** | **-** | **0.1373** | **-** | **-** | **288 B** | -| _PrimitiveStringDeserialize | MessagePack_NoComp | 103.104 ns | NA | - | 0.1070 | - | - | 224 B | -| _PrimitiveStringDeserialize | ProtobufNet | 305.879 ns | NA | - | 0.1488 | - | - | 312 B | -| _PrimitiveStringDeserialize | JsonNet | 914.114 ns | NA | - | 2.8152 | - | - | 5,896 B | -| _PrimitiveStringDeserialize | BinaryFormatter | 757.687 ns | NA | - | 1.2236 | - | - | 2,560 B | -| _PrimitiveStringDeserialize | DataContract | 1,679.119 ns | NA | - | 2.2297 | - | - | 4,664 B | -| _PrimitiveStringDeserialize | Jil | 416.432 ns | NA | - | 0.3977 | - | - | 832 B | -| _PrimitiveStringDeserialize | SpanJson | 135.532 ns | NA | - | 0.1070 | - | - | 224 B | -| _PrimitiveStringDeserialize | UTF8Json | 264.365 ns | NA | - | 0.1068 | - | - | 224 B | -| _PrimitiveStringDeserialize | FsPickler | 491.160 ns | NA | - | 0.5927 | - | - | 1,240 B | -| _PrimitiveStringDeserialize | Ceras | 157.259 ns | NA | - | 0.1070 | - | - | 224 B | -| _PrimitiveStringDeserialize | Odin | 374.535 ns | NA | - | 0.1068 | - | - | 224 B | -| _PrimitiveStringDeserialize | Nino | 36.583 ns | NA | - | 0.1071 | - | - | 224 B | -| **_PrimitiveStringSerialize** | **MessagePack_Lz4** | **411.009 ns** | **NA** | **21 B** | **0.0534** | **-** | **-** | **112 B** | -| _PrimitiveStringSerialize | MessagePack_NoComp | 81.912 ns | NA | 102 B | 0.0612 | - | - | 128 B | -| _PrimitiveStringSerialize | ProtobufNet | 305.328 ns | NA | 102 B | 0.2255 | - | - | 472 B | -| _PrimitiveStringSerialize | JsonNet | 453.027 ns | NA | 105 B | 1.4682 | - | - | 3,072 B | -| _PrimitiveStringSerialize | BinaryFormatter | 736.647 ns | NA | 124 B | 1.1778 | - | - | 2,464 B | -| _PrimitiveStringSerialize | DataContract | 654.075 ns | NA | 177 B | 0.8564 | - | - | 1,792 B | -| _PrimitiveStringSerialize | Jil | 503.522 ns | NA | 102 B | 0.4320 | - | - | 904 B | -| _PrimitiveStringSerialize | SpanJson | 174.507 ns | NA | 102 B | 0.0610 | - | - | 128 B | -| _PrimitiveStringSerialize | UTF8Json | 135.569 ns | NA | 102 B | 0.0610 | - | - | 128 B | -| _PrimitiveStringSerialize | FsPickler | 462.445 ns | NA | 127 B | 0.5736 | - | - | 1,200 B | -| _PrimitiveStringSerialize | Ceras | 347.374 ns | NA | 101 B | 2.0280 | - | - | 4,248 B | -| _PrimitiveStringSerialize | Odin | 315.643 ns | NA | 206 B | 0.1106 | - | - | 232 B | -| _PrimitiveStringSerialize | Nino | 56.208 ns | NA | 206 B | 0.1109 | - | - | 232 B | -| **_PrimitiveUIntDeserialize** | **MessagePack_Lz4** | **139.739 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveUIntDeserialize | MessagePack_NoComp | 36.001 ns | NA | - | - | - | - | - | -| _PrimitiveUIntDeserialize | ProtobufNet | 289.657 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveUIntDeserialize | JsonNet | 762.139 ns | NA | - | 2.7218 | - | - | 5,696 B | -| _PrimitiveUIntDeserialize | BinaryFormatter | 1,893.910 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveUIntDeserialize | DataContract | 1,376.241 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveUIntDeserialize | Jil | 66.243 ns | NA | - | 0.0573 | - | - | 120 B | -| _PrimitiveUIntDeserialize | SpanJson | 11.823 ns | NA | - | - | - | - | - | -| _PrimitiveUIntDeserialize | UTF8Json | 19.989 ns | NA | - | - | - | - | - | -| _PrimitiveUIntDeserialize | FsPickler | 404.997 ns | NA | - | 0.4854 | - | - | 1,016 B | -| _PrimitiveUIntDeserialize | Ceras | 84.606 ns | NA | - | - | - | - | - | -| _PrimitiveUIntDeserialize | Odin | 339.061 ns | NA | - | - | - | - | - | -| _PrimitiveUIntDeserialize | Nino | 7.123 ns | NA | - | - | - | - | - | -| **_PrimitiveUIntSerialize** | **MessagePack_Lz4** | **89.775 ns** | **NA** | **1 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveUIntSerialize | MessagePack_NoComp | 56.141 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| _PrimitiveUIntSerialize | ProtobufNet | 153.254 ns | NA | 2 B | 0.1798 | - | - | 376 B | -| _PrimitiveUIntSerialize | JsonNet | 343.112 ns | NA | 4 B | 1.3847 | - | - | 2,896 B | -| _PrimitiveUIntSerialize | BinaryFormatter | 1,088.794 ns | NA | 55 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveUIntSerialize | DataContract | 528.015 ns | NA | 88 B | 0.8221 | - | - | 1,720 B | -| _PrimitiveUIntSerialize | Jil | 96.772 ns | NA | 1 B | 0.1224 | - | - | 256 B | -| _PrimitiveUIntSerialize | SpanJson | 65.505 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| _PrimitiveUIntSerialize | UTF8Json | 40.335 ns | NA | 1 B | 0.0153 | - | - | 32 B | -| _PrimitiveUIntSerialize | FsPickler | 370.443 ns | NA | 29 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveUIntSerialize | Ceras | 305.704 ns | NA | 1 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveUIntSerialize | Odin | 298.573 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveUIntSerialize | Nino | 48.857 ns | NA | 4 B | 0.0153 | - | - | 32 B | -| **_PrimitiveULongDeserialize** | **MessagePack_Lz4** | **143.216 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveULongDeserialize | MessagePack_NoComp | 40.888 ns | NA | - | - | - | - | - | -| _PrimitiveULongDeserialize | ProtobufNet | 236.009 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveULongDeserialize | JsonNet | 1,120.918 ns | NA | - | 2.8839 | - | - | 6,032 B | -| _PrimitiveULongDeserialize | BinaryFormatter | 1,874.674 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveULongDeserialize | DataContract | 1,530.888 ns | NA | - | 2.0390 | - | - | 4,264 B | -| _PrimitiveULongDeserialize | Jil | 118.374 ns | NA | - | 0.0763 | - | - | 160 B | -| _PrimitiveULongDeserialize | SpanJson | 89.839 ns | NA | - | - | - | - | - | -| _PrimitiveULongDeserialize | UTF8Json | 55.491 ns | NA | - | - | - | - | - | -| _PrimitiveULongDeserialize | FsPickler | 401.665 ns | NA | - | 0.4854 | - | - | 1,016 B | -| _PrimitiveULongDeserialize | Ceras | 84.624 ns | NA | - | - | - | - | - | -| _PrimitiveULongDeserialize | Odin | 338.834 ns | NA | - | - | - | - | - | -| _PrimitiveULongDeserialize | Nino | 7.162 ns | NA | - | - | - | - | - | -| **_PrimitiveULongSerialize** | **MessagePack_Lz4** | **87.655 ns** | **NA** | **9 B** | **0.0497** | **-** | **-** | **104 B** | -| _PrimitiveULongSerialize | MessagePack_NoComp | 58.862 ns | NA | 9 B | 0.0191 | - | - | 40 B | -| _PrimitiveULongSerialize | ProtobufNet | 160.003 ns | NA | 11 B | 0.1836 | - | - | 384 B | -| _PrimitiveULongSerialize | JsonNet | 388.431 ns | NA | 23 B | 1.4381 | - | - | 3,008 B | -| _PrimitiveULongSerialize | BinaryFormatter | 1,165.139 ns | NA | 59 B | 1.4725 | - | - | 3,080 B | -| _PrimitiveULongSerialize | DataContract | 569.190 ns | NA | 109 B | 0.8640 | - | - | 1,808 B | -| _PrimitiveULongSerialize | Jil | 154.808 ns | NA | 20 B | 0.1988 | - | - | 416 B | -| _PrimitiveULongSerialize | SpanJson | 88.067 ns | NA | 20 B | 0.0229 | - | - | 48 B | -| _PrimitiveULongSerialize | UTF8Json | 64.812 ns | NA | 20 B | 0.0229 | - | - | 48 B | -| _PrimitiveULongSerialize | FsPickler | 361.423 ns | NA | 33 B | 0.5317 | - | - | 1,112 B | -| _PrimitiveULongSerialize | Ceras | 304.939 ns | NA | 8 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveULongSerialize | Odin | 301.618 ns | NA | 9 B | 0.0191 | - | - | 40 B | -| _PrimitiveULongSerialize | Nino | 46.257 ns | NA | 8 B | 0.0153 | - | - | 32 B | -| **_PrimitiveUShortDeserialize** | **MessagePack_Lz4** | **147.326 ns** | **NA** | **-** | **0.0305** | **-** | **-** | **64 B** | -| _PrimitiveUShortDeserialize | MessagePack_NoComp | 40.951 ns | NA | - | - | - | - | - | -| _PrimitiveUShortDeserialize | ProtobufNet | 233.048 ns | NA | - | 0.0420 | - | - | 88 B | -| _PrimitiveUShortDeserialize | JsonNet | 856.226 ns | NA | - | 2.7342 | - | - | 5,720 B | -| _PrimitiveUShortDeserialize | BinaryFormatter | 1,893.253 ns | NA | - | 1.9684 | - | - | 4,120 B | -| _PrimitiveUShortDeserialize | DataContract | 1,403.789 ns | NA | - | 1.9760 | - | - | 4,136 B | -| _PrimitiveUShortDeserialize | Jil | 74.119 ns | NA | - | 0.0612 | - | - | 128 B | -| _PrimitiveUShortDeserialize | SpanJson | 16.704 ns | NA | - | - | - | - | - | -| _PrimitiveUShortDeserialize | UTF8Json | 24.610 ns | NA | - | - | - | - | - | -| _PrimitiveUShortDeserialize | FsPickler | 399.789 ns | NA | - | 0.4854 | - | - | 1,016 B | -| _PrimitiveUShortDeserialize | Ceras | 81.677 ns | NA | - | - | - | - | - | -| _PrimitiveUShortDeserialize | Odin | 370.366 ns | NA | - | - | - | - | - | -| _PrimitiveUShortDeserialize | Nino | 6.996 ns | NA | - | - | - | - | - | -| **_PrimitiveUShortSerialize** | **MessagePack_Lz4** | **85.480 ns** | **NA** | **3 B** | **0.0459** | **-** | **-** | **96 B** | -| _PrimitiveUShortSerialize | MessagePack_NoComp | 57.257 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveUShortSerialize | ProtobufNet | 154.073 ns | NA | 4 B | 0.1798 | - | - | 376 B | -| _PrimitiveUShortSerialize | JsonNet | 368.378 ns | NA | 8 B | 1.4305 | - | - | 2,992 B | -| _PrimitiveUShortSerialize | BinaryFormatter | 1,098.065 ns | NA | 53 B | 1.4687 | - | - | 3,072 B | -| _PrimitiveUShortSerialize | DataContract | 520.625 ns | NA | 96 B | 0.8259 | - | - | 1,728 B | -| _PrimitiveUShortSerialize | Jil | 100.528 ns | NA | 5 B | 0.1262 | - | - | 264 B | -| _PrimitiveUShortSerialize | SpanJson | 79.631 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveUShortSerialize | UTF8Json | 43.899 ns | NA | 5 B | 0.0153 | - | - | 32 B | -| _PrimitiveUShortSerialize | FsPickler | 365.194 ns | NA | 27 B | 0.5279 | - | - | 1,104 B | -| _PrimitiveUShortSerialize | Ceras | 296.994 ns | NA | 2 B | 1.9841 | - | - | 4,152 B | -| _PrimitiveUShortSerialize | Odin | 293.916 ns | NA | 3 B | 0.0153 | - | - | 32 B | -| _PrimitiveUShortSerialize | Nino | 46.019 ns | NA | 2 B | 0.0153 | - | - | 32 B | -| **AccessTokenDeserialize** | **MessagePack_Lz4** | **249.550 ns** | **NA** | **-** | **0.0534** | **-** | **-** | **112 B** | -| AccessTokenDeserialize | MessagePack_NoComp | 145.882 ns | NA | - | 0.0229 | - | - | 48 B | -| AccessTokenDeserialize | ProtobufNet | 353.008 ns | NA | - | 0.0648 | - | - | 136 B | -| AccessTokenDeserialize | JsonNet | 1,689.592 ns | NA | - | 2.7542 | - | - | 5,768 B | -| AccessTokenDeserialize | BinaryFormatter | 2,731.956 ns | NA | - | 2.5024 | - | - | 5,240 B | -| AccessTokenDeserialize | DataContract | 3,667.565 ns | NA | - | 4.1237 | - | - | 8,632 B | -| AccessTokenDeserialize | Jil | 313.271 ns | NA | - | 0.1564 | - | - | 328 B | -| AccessTokenDeserialize | SpanJson | 95.724 ns | NA | - | 0.0229 | - | - | 48 B | -| AccessTokenDeserialize | UTF8Json | 271.678 ns | NA | - | 0.0229 | - | - | 48 B | -| AccessTokenDeserialize | FsPickler | 531.018 ns | NA | - | 0.5922 | - | - | 1,240 B | -| AccessTokenDeserialize | Ceras | 273.794 ns | NA | - | 0.0229 | - | - | 48 B | -| AccessTokenDeserialize | Odin | 1,890.117 ns | NA | - | 0.3014 | - | - | 632 B | -| AccessTokenDeserialize | Nino | 41.652 ns | NA | - | 0.0229 | - | - | 48 B | -| **AccessTokenSerialize** | **MessagePack_Lz4** | **352.738 ns** | **NA** | **19 B** | **0.0534** | **-** | **-** | **112 B** | -| AccessTokenSerialize | MessagePack_NoComp | 132.470 ns | NA | 19 B | 0.0229 | - | - | 48 B | -| AccessTokenSerialize | ProtobufNet | 319.258 ns | NA | 6 B | 0.1798 | - | - | 376 B | -| AccessTokenSerialize | JsonNet | 905.380 ns | NA | 82 B | 1.5059 | - | - | 3,152 B | -| AccessTokenSerialize | BinaryFormatter | 2,763.771 ns | NA | 392 B | 2.3346 | - | - | 4,888 B | -| AccessTokenSerialize | DataContract | 1,583.432 ns | NA | 333 B | 1.2798 | - | - | 2,680 B | -| AccessTokenSerialize | Jil | 454.528 ns | NA | 80 B | 0.4435 | - | - | 928 B | -| AccessTokenSerialize | SpanJson | 108.356 ns | NA | 53 B | 0.0381 | - | - | 80 B | -| AccessTokenSerialize | UTF8Json | 195.958 ns | NA | 79 B | 0.0496 | - | - | 104 B | -| AccessTokenSerialize | FsPickler | 616.381 ns | NA | 67 B | 0.5732 | - | - | 1,200 B | -| AccessTokenSerialize | Ceras | 565.154 ns | NA | 12 B | 1.9875 | - | - | 4,160 B | -| AccessTokenSerialize | Odin | 1,355.360 ns | NA | 440 B | 0.2441 | - | - | 512 B | -| AccessTokenSerialize | Nino | 67.938 ns | NA | 18 B | 0.0229 | - | - | 48 B | -| **AccountMergeDeserialize** | **MessagePack_Lz4** | **225.228 ns** | **NA** | **-** | **0.0458** | **-** | **-** | **96 B** | -| AccountMergeDeserialize | MessagePack_NoComp | 243.476 ns | NA | - | 0.0153 | - | - | 32 B | -| AccountMergeDeserialize | ProtobufNet | 842.079 ns | NA | - | 0.0572 | - | - | 120 B | -| AccountMergeDeserialize | JsonNet | 1,630.125 ns | NA | - | 2.7466 | - | - | 5,752 B | -| AccountMergeDeserialize | BinaryFormatter | 3,492.414 ns | NA | - | 2.3155 | - | - | 4,848 B | -| AccountMergeDeserialize | DataContract | 8,672.817 ns | NA | - | 5.9814 | - | - | 12,536 B | -| AccountMergeDeserialize | Jil | 353.636 ns | NA | - | 0.1411 | - | - | 296 B | -| AccountMergeDeserialize | SpanJson | 119.976 ns | NA | - | 0.0153 | - | - | 32 B | -| AccountMergeDeserialize | UTF8Json | 242.910 ns | NA | - | 0.0153 | - | - | 32 B | -| AccountMergeDeserialize | FsPickler | 505.434 ns | NA | - | 0.5884 | - | - | 1,232 B | -| AccountMergeDeserialize | Ceras | 269.913 ns | NA | - | 0.0153 | - | - | 32 B | -| AccountMergeDeserialize | Odin | 1,600.680 ns | NA | - | 0.2747 | - | - | 576 B | -| AccountMergeDeserialize | Nino | 14.258 ns | NA | - | 0.0153 | - | - | 32 B | -| **AccountMergeSerialize** | **MessagePack_Lz4** | **342.455 ns** | **NA** | **18 B** | **0.0534** | **-** | **-** | **112 B** | -| AccountMergeSerialize | MessagePack_NoComp | 95.773 ns | NA | 18 B | 0.0229 | - | - | 48 B | -| AccountMergeSerialize | ProtobufNet | 335.132 ns | NA | 6 B | 0.1798 | - | - | 376 B | -| AccountMergeSerialize | JsonNet | 895.350 ns | NA | 72 B | 1.5106 | - | - | 3,160 B | -| AccountMergeSerialize | BinaryFormatter | 2,409.453 ns | NA | 250 B | 1.8501 | - | - | 3,872 B | -| AccountMergeSerialize | DataContract | 1,288.189 ns | NA | 253 B | 1.1806 | - | - | 2,472 B | -| AccountMergeSerialize | Jil | 420.881 ns | NA | 70 B | 0.3443 | - | - | 720 B | -| AccountMergeSerialize | SpanJson | 125.590 ns | NA | 69 B | 0.0458 | - | - | 96 B | -| AccountMergeSerialize | UTF8Json | 173.364 ns | NA | 69 B | 0.0458 | - | - | 96 B | -| AccountMergeSerialize | FsPickler | 616.774 ns | NA | 67 B | 0.5732 | - | - | 1,200 B | -| AccountMergeSerialize | Ceras | 518.293 ns | NA | 11 B | 1.9875 | - | - | 4,160 B | -| AccountMergeSerialize | Odin | 1,242.706 ns | NA | 408 B | 0.2403 | - | - | 504 B | -| AccountMergeSerialize | Nino | 60.147 ns | NA | 18 B | 0.0229 | - | - | 48 B | -| **AnswerDeserialize** | **MessagePack_Lz4** | **822.464 ns** | **NA** | **-** | **0.0992** | **-** | **-** | **208 B** | -| AnswerDeserialize | MessagePack_NoComp | 411.544 ns | NA | - | 0.0687 | - | - | 144 B | -| AnswerDeserialize | ProtobufNet | 585.853 ns | NA | - | 0.1106 | - | - | 232 B | -| AnswerDeserialize | JsonNet | 15,239.784 ns | NA | - | 2.8839 | - | - | 6,056 B | -| AnswerDeserialize | BinaryFormatter | 7,828.262 ns | NA | - | 4.1962 | - | - | 8,784 B | -| AnswerDeserialize | DataContract | 9,294.727 ns | NA | - | 6.4087 | - | - | 13,392 B | -| AnswerDeserialize | Jil | 1,712.727 ns | NA | - | 0.5646 | - | - | 1,184 B | -| AnswerDeserialize | SpanJson | 572.279 ns | NA | - | 0.0687 | - | - | 144 B | -| AnswerDeserialize | UTF8Json | 1,214.343 ns | NA | - | 0.0687 | - | - | 144 B | -| AnswerDeserialize | FsPickler | 675.320 ns | NA | - | 0.6342 | - | - | 1,328 B | -| AnswerDeserialize | Ceras | 543.900 ns | NA | - | 0.0687 | - | - | 144 B | -| AnswerDeserialize | Odin | 6,083.301 ns | NA | - | 1.1520 | - | - | 2,416 B | -| AnswerDeserialize | Nino | 63.392 ns | NA | - | 0.0688 | - | - | 144 B | -| **AnswerSerialize** | **MessagePack_Lz4** | **1,116.501 ns** | **NA** | **53 B** | **0.0687** | **-** | **-** | **144 B** | -| AnswerSerialize | MessagePack_NoComp | 290.072 ns | NA | 97 B | 0.0610 | - | - | 128 B | -| AnswerSerialize | ProtobufNet | 530.705 ns | NA | 30 B | 0.1907 | - | - | 400 B | -| AnswerSerialize | JsonNet | 3,340.096 ns | NA | 458 B | 3.5744 | - | - | 7,480 B | -| AnswerSerialize | BinaryFormatter | 7,903.100 ns | NA | 1117 B | 5.0354 | - | - | 10,552 B | -| AnswerSerialize | DataContract | 3,938.859 ns | NA | 883 B | 2.7542 | - | - | 5,768 B | -| AnswerSerialize | Jil | 1,518.566 ns | NA | 460 B | 1.4248 | - | - | 2,984 B | -| AnswerSerialize | SpanJson | 430.867 ns | NA | 353 B | 0.1836 | - | - | 384 B | -| AnswerSerialize | UTF8Json | 766.091 ns | NA | 455 B | 0.2289 | - | - | 480 B | -| AnswerSerialize | FsPickler | 818.440 ns | NA | 130 B | 0.6037 | - | - | 1,264 B | -| AnswerSerialize | Ceras | 536.302 ns | NA | 58 B | 2.0113 | - | - | 4,208 B | -| AnswerSerialize | Odin | 4,359.471 ns | NA | 1584 B | 0.9384 | - | - | 1,968 B | -| AnswerSerialize | Nino | 176.799 ns | NA | 84 B | 0.0534 | - | - | 112 B | -| **BadgeDeserialize** | **MessagePack_Lz4** | **257.866 ns** | **NA** | **-** | **0.0534** | **-** | **-** | **112 B** | -| BadgeDeserialize | MessagePack_NoComp | 151.698 ns | NA | - | 0.0229 | - | - | 48 B | -| BadgeDeserialize | ProtobufNet | 247.663 ns | NA | - | 0.0648 | - | - | 136 B | -| BadgeDeserialize | JsonNet | 1,631.568 ns | NA | - | 2.7332 | - | - | 5,720 B | -| BadgeDeserialize | BinaryFormatter | 2,614.842 ns | NA | - | 2.4223 | - | - | 5,072 B | -| BadgeDeserialize | DataContract | 3,308.971 ns | NA | - | 4.0131 | - | - | 8,400 B | -| BadgeDeserialize | Jil | 205.040 ns | NA | - | 0.1490 | - | - | 312 B | -| BadgeDeserialize | SpanJson | 56.100 ns | NA | - | 0.0229 | - | - | 48 B | -| BadgeDeserialize | UTF8Json | 193.397 ns | NA | - | 0.0229 | - | - | 48 B | -| BadgeDeserialize | FsPickler | 473.412 ns | NA | - | 0.5889 | - | - | 1,232 B | -| BadgeDeserialize | Ceras | 244.302 ns | NA | - | 0.0229 | - | - | 48 B | -| BadgeDeserialize | Odin | 1,548.200 ns | NA | - | 0.2708 | - | - | 568 B | -| BadgeDeserialize | Nino | 22.069 ns | NA | - | 0.0229 | - | - | 48 B | -| **BadgeSerialize** | **MessagePack_Lz4** | **370.105 ns** | **NA** | **9 B** | **0.0496** | **-** | **-** | **104 B** | -| BadgeSerialize | MessagePack_NoComp | 136.893 ns | NA | 9 B | 0.0191 | - | - | 40 B | -| BadgeSerialize | ProtobufNet | 201.237 ns | NA | 0 B | 0.0305 | - | - | 64 B | -| BadgeSerialize | JsonNet | 911.790 ns | NA | 74 B | 1.4572 | - | - | 3,048 B | -| BadgeSerialize | BinaryFormatter | 2,540.477 ns | NA | 278 B | 2.1515 | - | - | 4,504 B | -| BadgeSerialize | DataContract | 1,337.075 ns | NA | 250 B | 1.0128 | - | - | 2,120 B | -| BadgeSerialize | Jil | 360.179 ns | NA | 71 B | 0.4320 | - | - | 904 B | -| BadgeSerialize | SpanJson | 83.969 ns | NA | 28 B | 0.0267 | - | - | 56 B | -| BadgeSerialize | UTF8Json | 119.922 ns | NA | 71 B | 0.0458 | - | - | 96 B | -| BadgeSerialize | FsPickler | 613.739 ns | NA | 54 B | 0.5655 | - | - | 1,184 B | -| BadgeSerialize | Ceras | 500.318 ns | NA | 6 B | 1.9836 | - | - | 4,152 B | -| BadgeSerialize | Odin | 1,324.928 ns | NA | 382 B | 0.2174 | - | - | 456 B | -| BadgeSerialize | Nino | 70.633 ns | NA | 16 B | 0.0191 | - | - | 40 B | -| **CommentDeserialize** | **MessagePack_Lz4** | **334.182 ns** | **NA** | **-** | **0.0610** | **-** | **-** | **128 B** | -| CommentDeserialize | MessagePack_NoComp | 181.110 ns | NA | - | 0.0305 | - | - | 64 B | -| CommentDeserialize | ProtobufNet | 295.744 ns | NA | - | 0.0725 | - | - | 152 B | -| CommentDeserialize | JsonNet | 2,383.058 ns | NA | - | 2.7618 | - | - | 5,784 B | -| CommentDeserialize | BinaryFormatter | 3,624.930 ns | NA | - | 2.7885 | - | - | 5,832 B | -| CommentDeserialize | DataContract | 4,538.462 ns | NA | - | 6.0806 | - | - | 12,728 B | -| CommentDeserialize | Jil | 428.218 ns | NA | - | 0.2294 | - | - | 480 B | -| CommentDeserialize | SpanJson | 153.482 ns | NA | - | 0.0305 | - | - | 64 B | -| CommentDeserialize | UTF8Json | 381.547 ns | NA | - | 0.0305 | - | - | 64 B | -| CommentDeserialize | FsPickler | 477.299 ns | NA | - | 0.5960 | - | - | 1,248 B | -| CommentDeserialize | Ceras | 266.978 ns | NA | - | 0.0305 | - | - | 64 B | -| CommentDeserialize | Odin | 2,442.528 ns | NA | - | 0.5150 | - | - | 1,080 B | -| CommentDeserialize | Nino | 27.568 ns | NA | - | 0.0306 | - | - | 64 B | -| **CommentSerialize** | **MessagePack_Lz4** | **402.587 ns** | **NA** | **27 B** | **0.0572** | **-** | **-** | **120 B** | -| CommentSerialize | MessagePack_NoComp | 170.648 ns | NA | 27 B | 0.0267 | - | - | 56 B | -| CommentSerialize | ProtobufNet | 335.129 ns | NA | 6 B | 0.1798 | - | - | 376 B | -| CommentSerialize | JsonNet | 1,457.594 ns | NA | 151 B | 1.5831 | - | - | 3,312 B | -| CommentSerialize | BinaryFormatter | 3,649.472 ns | NA | 403 B | 2.3956 | - | - | 5,016 B | -| CommentSerialize | DataContract | 1,828.150 ns | NA | 361 B | 1.2875 | - | - | 2,696 B | -| CommentSerialize | Jil | 675.614 ns | NA | 149 B | 0.5693 | - | - | 1,192 B | -| CommentSerialize | SpanJson | 148.153 ns | NA | 104 B | 0.0610 | - | - | 128 B | -| CommentSerialize | UTF8Json | 272.405 ns | NA | 148 B | 0.0839 | - | - | 176 B | -| CommentSerialize | FsPickler | 676.867 ns | NA | 71 B | 0.5732 | - | - | 1,200 B | -| CommentSerialize | Ceras | 542.838 ns | NA | 17 B | 1.9913 | - | - | 4,168 B | -| CommentSerialize | Odin | 2,077.209 ns | NA | 708 B | 0.4196 | - | - | 880 B | -| CommentSerialize | Nino | 98.829 ns | NA | 30 B | 0.0267 | - | - | 56 B | -| **NestedDataDeserialize** | **MessagePack_Lz4** | **1,647,207.397 ns** | **NA** | **-** | **242.1875** | **242.1875** | **242.1875** | **940,524 B** | -| NestedDataDeserialize | MessagePack_NoComp | 1,627,367.430 ns | NA | - | 140.6250 | 140.6250 | 140.6250 | 560,181 B | -| NestedDataDeserialize | ProtobufNet | 2,030,716.145 ns | NA | - | 132.8125 | 132.8125 | 132.8125 | 561,363 B | -| NestedDataDeserialize | JsonNet | 23,441,751.312 ns | NA | - | 2375.0000 | 687.5000 | 562.5000 | 6,082,907 B | -| NestedDataDeserialize | BinaryFormatter | 34,384,927.800 ns | NA | - | 3400.0000 | 1200.0000 | 600.0000 | 12,696,020 B | -| NestedDataDeserialize | DataContract | 22,034,322.938 ns | NA | - | 1500.0000 | 468.7500 | 468.7500 | 4,489,114 B | -| NestedDataDeserialize | Jil | 5,994,985.031 ns | NA | - | 1492.1875 | 984.3750 | 976.5625 | 5,378,328 B | -| NestedDataDeserialize | SpanJson | 3,181,319.576 ns | NA | - | 97.6563 | 97.6563 | 97.6563 | 560,972 B | -| NestedDataDeserialize | UTF8Json | 8,334,485.031 ns | NA | - | 734.3750 | 468.7500 | 468.7500 | 2,449,194 B | -| NestedDataDeserialize | FsPickler | 736,832.479 ns | NA | - | 133.7891 | 132.8125 | 132.8125 | 562,184 B | -| NestedDataDeserialize | Ceras | 52,568.774 ns | NA | - | 59.0210 | 58.4717 | 58.4717 | 560,549 B | -| NestedDataDeserialize | Odin | 22,131,333.312 ns | NA | - | 2750.0000 | 312.5000 | 312.5000 | 6,996,090 B | -| NestedDataDeserialize | Nino | 52,758.466 ns | NA | - | 81.7871 | 81.1157 | 81.1157 | 560,681 B | -| **NestedDataSerialize** | **MessagePack_Lz4** | **1,096,706.258 ns** | **NA** | **1553 B** | **-** | **-** | **-** | **1,650 B** | -| NestedDataSerialize | MessagePack_NoComp | 1,137,632.162 ns | NA | 380010 B | 97.6563 | 97.6563 | 97.6563 | 380,106 B | -| NestedDataSerialize | ProtobufNet | 1,812,959.635 ns | NA | 410006 B | 394.5313 | 335.9375 | 332.0313 | 1,465,476 B | -| NestedDataSerialize | JsonNet | 17,805,178.375 ns | NA | 920025 B | 2625.0000 | 718.7500 | 687.5000 | 6,950,126 B | -| NestedDataSerialize | BinaryFormatter | 61,950,829.100 ns | NA | 580388 B | 3600.0000 | 600.0000 | 500.0000 | 9,165,155 B | -| NestedDataSerialize | DataContract | 19,313,885.438 ns | NA | 1190173 B | 2031.2500 | 625.0000 | 593.7500 | 8,184,938 B | -| NestedDataSerialize | Jil | 21,180,697.281 ns | NA | 1010022 B | 1250.0000 | 937.5000 | 468.7500 | 6,513,530 B | -| NestedDataSerialize | SpanJson | 7,003,992.676 ns | NA | 1010022 B | 179.6875 | 179.6875 | 179.6875 | 1,010,171 B | -| NestedDataSerialize | UTF8Json | 7,813,969.062 ns | NA | 1010022 B | 1062.5000 | 640.6250 | 640.6250 | 3,857,248 B | -| NestedDataSerialize | FsPickler | 2,363,512.775 ns | NA | 470066 B | 390.6250 | 332.0313 | 328.1250 | 1,520,604 B | -| NestedDataSerialize | Ceras | 191,736.003 ns | NA | 560009 B | 77.8809 | 75.4395 | 75.4395 | 1,612,991 B | -| NestedDataSerialize | Odin | 26,701,454.406 ns | NA | 1280351 B | 4812.5000 | 937.5000 | 875.0000 | 12,728,596 B | -| NestedDataSerialize | Nino | 291,598.938 ns | NA | 560022 B | 126.9531 | 125.4883 | 125.4883 | 561,173 B | +| Method | Categories | Mean | Error | StdDev | Median | Min | Max | Ratio | RatioSD | Payload | +| ----------------------------------- | ------------------------ | --------------:| -----------:| -----------:| --------------:| --------------:| --------------:| -----:| -------:| --------:| +| MessagePackDeserializeSimpleClass | SimpleClassDeserialize | 1,148.2660 ns | 8.8036 ns | 4.6045 ns | 1,149.4530 ns | 1,139.8289 ns | 1,154.8804 ns | 1.00 | 0.00 | - | +| MemoryPackDeserializeSimpleClass | SimpleClassDeserialize | 449.8288 ns | 80.2214 ns | 53.0615 ns | 417.1767 ns | 414.1244 ns | 552.1924 ns | 0.40 | 0.05 | - | +| NinoDeserializeSimpleClass | SimpleClassDeserialize | 298.9580 ns | 4.5691 ns | 2.3897 ns | 297.8766 ns | 296.8175 ns | 302.7422 ns | 0.26 | 0.00 | - | +| | | | | | | | | | | | +| MessagePackSerializeSimpleClass | SimpleClassSerialize | 1,296.4875 ns | 8.5089 ns | 5.6281 ns | 1,294.8236 ns | 1,288.4005 ns | 1,308.2755 ns | 1.00 | 0.00 | 674 B | +| MemoryPackSerializeSimpleClass | SimpleClassSerialize | 425.2460 ns | 13.3104 ns | 7.9208 ns | 422.3036 ns | 419.2683 ns | 443.3696 ns | 0.33 | 0.01 | 730 B | +| NinoSerializeSimpleClass | SimpleClassSerialize | 207.5860 ns | 2.8659 ns | 1.7055 ns | 207.1263 ns | 205.9621 ns | 211.1342 ns | 0.16 | 0.00 | 738 B | +| | | | | | | | | | | | +| MessagePackDeserializeSimpleClasses | SimpleClassesDeserialize | 34,063.6150 ns | 188.5014 ns | 112.1741 ns | 34,046.4960 ns | 33,931.1091 ns | 34,243.4489 ns | 1.00 | 0.00 | - | +| MemoryPackDeserializeSimpleClasses | SimpleClassesDeserialize | 12,436.6578 ns | 230.5653 ns | 137.2057 ns | 12,428.7631 ns | 12,297.8020 ns | 12,669.8284 ns | 0.37 | 0.00 | - | +| NinoDeserializeSimpleClasses | SimpleClassesDeserialize | 9,177.5588 ns | 48.4882 ns | 25.3603 ns | 9,178.1489 ns | 9,129.7035 ns | 9,208.5476 ns | 0.27 | 0.00 | - | +| | | | | | | | | | | | +| MessagePackSerializeSimpleClasses | SimpleClassesSerialize | 37,935.0473 ns | 122.6102 ns | 72.9634 ns | 37,967.4072 ns | 37,833.4935 ns | 38,030.5862 ns | 1.00 | 0.00 | 19.75 KB | +| MemoryPackSerializeSimpleClasses | SimpleClassesSerialize | 12,568.2318 ns | 167.2008 ns | 99.4985 ns | 12,513.6725 ns | 12,480.6849 ns | 12,734.0075 ns | 0.33 | 0.00 | 21.39 KB | +| NinoSerializeSimpleClasses | SimpleClassesSerialize | 5,404.4797 ns | 24.6760 ns | 12.9060 ns | 5,401.7556 ns | 5,388.4586 ns | 5,423.2680 ns | 0.14 | 0.00 | 21.63 KB | +| | | | | | | | | | | | +| MessagePackDeserializeSimpleStruct | SimpleStructDeserialize | 47.3220 ns | 0.1848 ns | 0.1100 ns | 47.3206 ns | 47.1874 ns | 47.5376 ns | 1.00 | 0.00 | - | +| MemoryPackDeserializeSimpleStruct | SimpleStructDeserialize | 1.5991 ns | 0.0052 ns | 0.0031 ns | 1.5996 ns | 1.5946 ns | 1.6045 ns | 0.03 | 0.00 | - | +| NinoDeserializeSimpleStruct | SimpleStructDeserialize | 0.5910 ns | 0.0424 ns | 0.0280 ns | 0.5705 ns | 0.5690 ns | 0.6393 ns | 0.01 | 0.00 | - | +| | | | | | | | | | | | +| MessagePackSerializeSimpleStruct | SimpleStructSerialize | 93.2237 ns | 0.0910 ns | 0.0602 ns | 93.2200 ns | 93.1300 ns | 93.3208 ns | 1.00 | 0.00 | 16 B | +| MemoryPackSerializeSimpleStruct | SimpleStructSerialize | 4.2233 ns | 0.0841 ns | 0.0500 ns | 4.2158 ns | 4.1699 ns | 4.3188 ns | 0.05 | 0.00 | 16 B | +| NinoSerializeSimpleStruct | SimpleStructSerialize | 4.1687 ns | 2.1087 ns | 1.3948 ns | 3.2187 ns | 3.1891 ns | 6.9510 ns | 0.04 | 0.01 | 16 B | +| | | | | | | | | | | | +| MessagePackDeserializeSimpleStructs | SimpleStructsDeserialize | 924.2507 ns | 91.8532 ns | 54.6604 ns | 895.5899 ns | 872.0001 ns | 1,039.7354 ns | 1.00 | 0.00 | - | +| MemoryPackDeserializeSimpleStructs | SimpleStructsDeserialize | 53.9092 ns | 12.0889 ns | 7.9961 ns | 49.8358 ns | 48.1084 ns | 68.8055 ns | 0.06 | 0.01 | - | +| NinoDeserializeSimpleStructs | SimpleStructsDeserialize | 31.7620 ns | 0.4291 ns | 0.2554 ns | 31.6444 ns | 31.4062 ns | 32.0834 ns | 0.03 | 0.00 | - | +| | | | | | | | | | | | +| MessagePackSerializeSimpleStructs | SimpleStructsSerialize | 2,264.9154 ns | 2.6982 ns | 1.7847 ns | 2,264.6615 ns | 2,262.4969 ns | 2,267.9900 ns | 1.00 | 0.00 | 483 B | +| MemoryPackSerializeSimpleStructs | SimpleStructsSerialize | 36.5122 ns | 0.8214 ns | 0.4296 ns | 36.5239 ns | 35.8662 ns | 37.0155 ns | 0.02 | 0.00 | 484 B | +| NinoSerializeSimpleStructs | SimpleStructsSerialize | 29.5231 ns | 0.4328 ns | 0.2863 ns | 29.4973 ns | 29.1184 ns | 30.0484 ns | 0.01 | 0.00 | 486 B | diff --git a/README.md b/README.md index 43e0745..f5d9c25 100644 --- a/README.md +++ b/README.md @@ -83,5 +83,5 @@ Definite useful and high performance serialisation library for C# projects, espe NuGet里搜```Nino``` ```bash - PM> Install-Package Nino -Version 2.0.1 + PM> Install-Package Nino -Version 2.0.2 ``` diff --git a/src/Nino.Benchmark/Data.cs b/src/Nino.Benchmark/Data.cs new file mode 100644 index 0000000..0966e25 --- /dev/null +++ b/src/Nino.Benchmark/Data.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using MemoryPack; +using MessagePack; +using Nino.Core; + +namespace Nino.Benchmark; + +[NinoType] +[MemoryPackable] +[MessagePackObject] +public partial class SimpleClass +{ + [Key(0)] + public int Id; + + [Key(1)] + public string Name { get; set; } + [Key(2)] + public int[] Numbers { get; set; } + [Key(3)] + public List Dates { get; set; } + + [Key(4)] + public Dictionary Map1; + + [Key(5)] + public Dictionary Map2 { get; set; } + + public static SimpleClass Create() + { + Random random = new Random(); + return new SimpleClass + { + Id = random.Next(), + Name = "SimpleClass", + Numbers = Enumerable.Range(0, 100).Select(n => random.Next()).ToArray(), + Dates = Enumerable.Range(0, 10).Select(n => DateTime.Now.AddSeconds(random.Next())).ToList(), + Map1 = Enumerable.Range(0, 10).ToDictionary(n => n, n => n.ToString()), + Map2 = Enumerable.Range(0, 10).ToDictionary(n => n, n => n * 2) + }; + } +} + +[NinoType] +[MemoryPackable] +[MessagePackObject] +public partial struct SimpleStruct +{ + [Key(0)] + public int Id; + [Key(1)] + public DateTime CreateTime; + + public static SimpleStruct Create() + { + Random random = new Random(); + return new SimpleStruct + { + Id = random.Next(), + CreateTime = DateTime.Now.AddSeconds(random.Next()) + }; + } +} \ No newline at end of file diff --git a/src/Nino.Benchmark/Nino.Benchmark.csproj b/src/Nino.Benchmark/Nino.Benchmark.csproj index 3ebdf00..c23d299 100644 --- a/src/Nino.Benchmark/Nino.Benchmark.csproj +++ b/src/Nino.Benchmark/Nino.Benchmark.csproj @@ -2,36 +2,32 @@ Exe - net6.0 + net8.0 disable enable true - - - - - - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - - - - - - Serialization\OdinSerializer.dll - - - - + + + + + - + + + + + diff --git a/src/Nino.Benchmark/PayloadColumn.cs b/src/Nino.Benchmark/PayloadColumn.cs new file mode 100644 index 0000000..4517edc --- /dev/null +++ b/src/Nino.Benchmark/PayloadColumn.cs @@ -0,0 +1,64 @@ +using System; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; + + +namespace Nino.Benchmark; +public class PayloadColumnAttribute : ColumnConfigBaseAttribute +{ + public PayloadColumnAttribute() + : base(new PayloadColumn()) + { + } +} + +public class PayloadColumn : IColumn +{ + public string Id => nameof(PayloadColumn); + + public string ColumnName => "Payload"; + + public bool AlwaysShow => true; + + public ColumnCategory Category => ColumnCategory.Custom; + + public int PriorityInCategory => 0; + + public bool IsNumeric => true; + + public UnitType UnitType => UnitType.Size; + + public string Legend => "Payload size"; + + public string GetValue(Summary summary, BenchmarkCase benchmarkCase) + { + var methodInfo = benchmarkCase.Descriptor.WorkloadMethod; + + if (methodInfo.ReturnType == typeof(byte[])) + { + var instance = Activator.CreateInstance(benchmarkCase.Descriptor.Type); + var result = (byte[])methodInfo.Invoke(instance, null)!; + return new SizeValue(result.LongLength).ToString(null); + } + else + { + return "-"; + } + } + + public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) + { + return GetValue(summary, benchmarkCase); + } + + public bool IsAvailable(Summary summary) + { + return true; + } + + public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) + { + return false; + } +} \ No newline at end of file diff --git a/src/Nino.Benchmark/Program.cs b/src/Nino.Benchmark/Program.cs index 7d85c88..6971252 100644 --- a/src/Nino.Benchmark/Program.cs +++ b/src/Nino.Benchmark/Program.cs @@ -6,11 +6,7 @@ public class Program { public static void Main(string[] args) { -#if !DEBUG - BenchmarkRunner.Run(); -#else - BenchmarkRunner.Run(new BenchmarkDotNet.Configs.DebugInProcessConfig()); -#endif + BenchmarkRunner.Run(typeof(Program).Assembly); } } } \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/BenchmarkConfig.cs b/src/Nino.Benchmark/Serialization/BenchmarkConfig.cs deleted file mode 100644 index 6ffd186..0000000 --- a/src/Nino.Benchmark/Serialization/BenchmarkConfig.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using BenchmarkDotNet.Columns; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Diagnosers; -using BenchmarkDotNet.Environments; -using BenchmarkDotNet.Exporters; -using BenchmarkDotNet.Exporters.Csv; -using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Order; -using BenchmarkDotNet.Reports; -using BenchmarkDotNet.Running; -using Perfolizer.Horology; - -namespace Nino.Benchmark -{ - public class BenchmarkConfig : ManualConfig - { - public BenchmarkConfig() - { - // run quickly:) - Job baseConfig = Job.ShortRun.WithIterationCount(1).WithWarmupCount(1); - - // Add(baseConfig.With(Runtime.Clr).With(Jit.RyuJit).With(Platform.X64)); - this.AddJob(baseConfig.WithRuntime(CoreRuntime.Core60).WithPlatform(Platform.AnyCpu)); - //this.AddJob(baseConfig.WithRuntime(ClrRuntime.Net48).WithPlatform(Platform.AnyCpu)); - //this.AddJob(baseConfig.WithJit(Jit.LegacyJit).WithRuntime(MonoRuntime.Default).WithPlatform(Platform.AnyCpu)); - //this.AddJob(baseConfig.WithJit(Jit.LegacyJit).WithPlatform(Platform.AnyCpu).WithRuntime(ClrRuntime.Net461)); - - this.AddExporter(MarkdownExporter.GitHub); - this.AddExporter(CsvExporter.Default); - this.AddDiagnoser(MemoryDiagnoser.Default); - - this.AddColumn(new DataSizeColumn()); - - this.Orderer = new CustomOrderer(); - } - - public class CustomOrderer : IOrderer - { - public bool SeparateLogicalGroups => false; - - public IEnumerable GetExecutionOrder(ImmutableArray benchmarksCase) - { - return benchmarksCase; - } - - public string GetHighlightGroupKey(BenchmarkCase benchmarkCase) - { - return benchmarkCase.Descriptor.MethodIndex.ToString(); - } - - public string GetLogicalGroupKey(ImmutableArray allBenchmarksCases, BenchmarkCase benchmarkCase) - { - return String.Empty; - } - - public IEnumerable> GetLogicalGroupOrder(IEnumerable> logicalGroups) - { - return logicalGroups; - } - - public IEnumerable GetSummaryOrder(ImmutableArray benchmarksCases, Summary summary) - { - return benchmarksCases - .OrderBy(x => x.Descriptor.WorkloadMethod.Name); - } - } - - public class DataSizeColumn : IColumn - { - public string Id => "DataSize"; - - public string ColumnName => "DataSize"; - - public bool AlwaysShow => true; - - public ColumnCategory Category => ColumnCategory.Custom; - - public int PriorityInCategory => int.MaxValue; - - public bool IsNumeric => true; - - public UnitType UnitType => UnitType.Size; - - public string Legend => string.Empty; - - public string GetValue(Summary summary, BenchmarkCase benchmarkCase) - { - return GetValue(summary, benchmarkCase, - new SummaryStyle(null, true, SizeUnit.B, TimeUnit.Millisecond)); - } - - public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) - { - System.Reflection.MethodInfo mi = benchmarkCase.Descriptor.WorkloadMethod; - if (!mi.Name.Contains("Serialize")) - { - return "-"; - } - - if (mi.DeclaringType != null) - { - var instance = Activator.CreateInstance(mi.DeclaringType); - mi.DeclaringType.GetField("Serializer")?.SetValue(instance, benchmarkCase.Parameters[0].Value); - mi.DeclaringType.GetMethod("Setup")?.Invoke(instance, null); - - var bytes = (byte[])mi.Invoke(instance, null)!; - var byteSize = bytes.Length; - var cultureInfo = summary.GetCultureInfo(); - if (style.PrintUnitsInContent) - { - return SizeValue.FromBytes(byteSize).ToString(style.SizeUnit, cultureInfo); - } - - return byteSize.ToString("0.##", cultureInfo); - } - - return "-"; - } - - public bool IsAvailable(Summary summary) - { - return true; - } - - public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) - { - return false; - } - } - } - public class BenchmarkConfig2 : ManualConfig - { - public BenchmarkConfig2() - { - // run quickly:) - Job baseConfig = Job.ShortRun.WithIterationCount(1).WithWarmupCount(1); - this.AddJob(baseConfig.WithRuntime(CoreRuntime.Core60).WithPlatform(Platform.AnyCpu)); - this.AddExporter(MarkdownExporter.GitHub); - this.AddExporter(CsvExporter.Default); - this.AddDiagnoser(MemoryDiagnoser.Default); - } - } - public class StrMgrBenchmarkConfig : ManualConfig - { - public StrMgrBenchmarkConfig() - { - // run quickly:) - Job baseConfig = Job.ShortRun.WithIterationCount(1).WithWarmupCount(1); - this.AddJob(baseConfig.WithRuntime(CoreRuntime.Core60).WithPlatform(Platform.AnyCpu)); - this.AddJob(baseConfig.WithRuntime(ClrRuntime.Net461).WithPlatform(Platform.AnyCpu)); - this.AddExporter(MarkdownExporter.GitHub); - this.AddExporter(CsvExporter.Default); - this.AddDiagnoser(MemoryDiagnoser.Default); - } - } -} diff --git a/src/Nino.Benchmark/Serialization/ExtensionMethods.cs b/src/Nino.Benchmark/Serialization/ExtensionMethods.cs deleted file mode 100644 index c911d6e..0000000 --- a/src/Nino.Benchmark/Serialization/ExtensionMethods.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -namespace Nino.Benchmark -{ - public static class ExtensionMethods - { - public static bool TrueEqualsString(this IEnumerable a, IEnumerable b) - { - return a.SequenceEqual(b); - } - - public static bool TrueEqualsString(this string a, string b) - { - return a == b; - } - - public static bool TrueEquals(this T? a, T? b) - where T : struct - { - if (!a.HasValue && !b.HasValue) - { - return true; - } - - if (!a.HasValue) - { - return false; - } - - if (!b.HasValue) - { - return false; - } - - return a.Value.Equals(b.Value); - } - - public static bool TrueEquals(this T a, T b) - { - if (a != null && a.Equals(b)) - { - return true; - } - - if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) - { - return true; - } - - if (ReferenceEquals(a, null)) - { - return false; - } - - if (ReferenceEquals(b, null)) - { - return false; - } - - return a.Equals(b); - } - - public static bool TrueEqualsList(this IEnumerable a, IEnumerable b) - where T : class, IGenericEquality - { - return a.SequenceEqual(b, GenericEqualityComparer.Default); - } - - public static bool TrueEqualsListDynamic(this IEnumerable a, IEnumerable b) - where T : class, IGenericEquality - { - if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) - { - return true; - } - - if (ReferenceEquals(a, null)) - { - return false; - } - - if (ReferenceEquals(b, null)) - { - return false; - } - - using (IEnumerator e1 = a.GetEnumerator()) - using (IEnumerator e2 = b.GetEnumerator()) - { - while (true) - { - var e1Next = e1.MoveNext(); - var e2Next = e2.MoveNext(); - if (e1Next != e2Next) - { - return false; - } - - if (!e1Next && !e2Next) - { - break; - } - - T c1 = e1.Current; - dynamic c2 = e2.Current; - - if (c1 == null && c2 != null) - { - return false; - } - - if (c2 == null && c1 != null) - { - return false; - } - - if (!c1?.EqualsDynamic(c2)) - { - return false; - } - } - } - - return true; - } - - public static bool IsTypedList(this Type type) - { - return - (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>)) || - type.GetTypeInfo().GetInterfaces().Any(i => - i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)); - } - - private class GenericEqualityComparer : IEqualityComparer - where T : class, IGenericEquality - { - public static readonly GenericEqualityComparer Default = new GenericEqualityComparer(); - - public bool Equals(T? x, T? y) - { - return x.TrueEquals(y); - } - - public int GetHashCode(T obj) - { - return 0; // not fast, but not really important here - } - } - } -} diff --git a/src/Nino.Benchmark/Serialization/IGenericEquality`1.cs b/src/Nino.Benchmark/Serialization/IGenericEquality`1.cs deleted file mode 100644 index ccb34f2..0000000 --- a/src/Nino.Benchmark/Serialization/IGenericEquality`1.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Nino.Benchmark -{ - public interface IGenericEquality - { - bool Equals(T obj); - - bool EqualsDynamic(dynamic obj); - } -} diff --git a/src/Nino.Benchmark/Serialization/Models/AccessToken.cs b/src/Nino.Benchmark/Serialization/Models/AccessToken.cs deleted file mode 100644 index 1e47329..0000000 --- a/src/Nino.Benchmark/Serialization/Models/AccessToken.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; -using MessagePack; -using Nino.Core; -using ProtoBuf; -#pragma warning disable 8618 - -namespace Nino.Benchmark.Models -{ - [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract] - [MessagePackObject] - [NinoType] - public partial class AccessToken : IGenericEquality - { - [System.Runtime.Serialization.DataMember, ProtoMember(1), Key(0), NinoMember(0)] - public string Token { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(2), Key(2 - 1), NinoMember(1)] - public DateTime ExpiresOnDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(3), Key(3 - 1), NinoMember(2)] - public int AccountId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(4), Key(4 - 1), NinoMember(3)] - public List Scope { get; set; } - - public bool Equals(AccessToken obj) - { - return - this.Token.TrueEqualsString(obj.Token) || - this.ExpiresOnDate.TrueEquals(obj.ExpiresOnDate) || - this.AccountId.TrueEquals(obj.AccountId) || - this.Scope.TrueEqualsString(obj.Scope); - } - - public bool EqualsDynamic(dynamic obj) - { - return - this.Token.TrueEqualsString((string)obj.access_token) || - this.ExpiresOnDate.TrueEquals((DateTime)obj.expires_on_date) || - this.AccountId.TrueEquals((int)obj.account_id) || - this.Scope.TrueEqualsString((IEnumerable)obj.scope); - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Models/AccountMerge.cs b/src/Nino.Benchmark/Serialization/Models/AccountMerge.cs deleted file mode 100644 index 52392be..0000000 --- a/src/Nino.Benchmark/Serialization/Models/AccountMerge.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using ProtoBuf; -using MessagePack; -using Nino.Core; - -namespace Nino.Benchmark.Models -{ - [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, MessagePackObject] - [NinoType] - public partial class AccountMerge : IGenericEquality - { - [System.Runtime.Serialization.DataMember, ProtoMember(1), Key(1 - 1), NinoMember(0)] - public int OldAccountId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(2), Key(2 - 1), NinoMember(1)] - public int NewAccountId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(3), Key(3 - 1), NinoMember(2)] - public DateTime MergeDate { get; set; } - - public bool Equals(AccountMerge obj) - { - return - this.OldAccountId.TrueEquals(obj.OldAccountId) && - this.NewAccountId.TrueEquals(obj.NewAccountId) && - this.MergeDate.TrueEquals(obj.MergeDate); - } - - public bool EqualsDynamic(dynamic obj) - { - return - this.OldAccountId.TrueEquals((int)obj.old_account_id) && - this.NewAccountId.TrueEquals((int)obj.new_account_id) && - this.MergeDate.TrueEquals((DateTime)obj.merge_date); - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Models/Answer.cs b/src/Nino.Benchmark/Serialization/Models/Answer.cs deleted file mode 100644 index 793b600..0000000 --- a/src/Nino.Benchmark/Serialization/Models/Answer.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable IDE1006 -#pragma warning disable SA1516 - -using System; -using System.Collections.Generic; -using ProtoBuf; -using MessagePack; -using Nino.Core; - -#pragma warning disable 8618 - -namespace Nino.Benchmark.Models -{ - [ProtoContract, Serializable, System.Runtime.Serialization.DataContract, MessagePackObject] - [NinoType] - public partial class Answer : IGenericEquality - { - [System.Runtime.Serialization.DataMember, ProtoMember(1), Key(1 - 1), NinoMember(0)] - public int QuestionId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(2), Key(2 - 1), NinoMember(1)] - public int AnswerId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(3), Key(3 - 1), NinoMember(2)] - public DateTime LockedDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(4), Key(4 - 1), NinoMember(3)] - public DateTime CreationDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(5), Key(5 - 1), NinoMember(4)] - public DateTime LastEditDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(6), Key(6 - 1), NinoMember(5)] - public DateTime LastActivityDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(7), Key(7 - 1), NinoMember(6)] - public int Score { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(8), Key(8 - 1), NinoMember(7)] - public DateTime CommunityOwnedDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(9), Key(9 - 1), NinoMember(8)] - public bool IsAccepted { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(10), Key(10 - 1), NinoMember(9)] - public string Body { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(12), Key(12 - 1), NinoMember(10)] - public string Title { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(13), Key(13 - 1), NinoMember(11)] - public int UpVoteCount { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(14), Key(14 - 1), NinoMember(12)] - public int DownVoteCount { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(15), Key(15 - 1), NinoMember(13)] - public List Comments { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(16), Key(16 - 1), NinoMember(14)] - public string Link { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(17), Key(17 - 1), NinoMember(15)] - public List Tags { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(18), Key(18 - 1), NinoMember(16)] - public bool Upvoted { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(19), Key(19 - 1), NinoMember(17)] - public bool Downvoted { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(20), Key(20 - 1), NinoMember(18)] - public bool Accepted { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(22), Key(22 - 1), NinoMember(19)] - public int CommentCount { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(23), Key(23 - 1), NinoMember(20)] - public string BodyMarkdown { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(24), Key(24 - 1), NinoMember(21)] - public string ShareLink { get; set; } - - public bool Equals(Answer obj) - { - return - this.Accepted.TrueEquals(obj.Accepted) && - this.AnswerId.TrueEquals(obj.AnswerId) && - this.Body.TrueEqualsString(obj.Body) && - this.BodyMarkdown.TrueEqualsString(obj.BodyMarkdown) && - this.CommentCount.TrueEquals(obj.CommentCount) && - this.Comments.TrueEqualsList(obj.Comments) && - this.CommunityOwnedDate.TrueEquals(obj.CommunityOwnedDate) && - this.CreationDate.TrueEquals(obj.CreationDate) && - this.DownVoteCount.TrueEquals(obj.DownVoteCount) && - this.Downvoted.TrueEquals(obj.Downvoted) && - this.IsAccepted.TrueEquals(obj.IsAccepted) && - this.LastActivityDate.TrueEquals(obj.LastActivityDate) && - this.LastEditDate.TrueEquals(obj.LastEditDate) && - this.Link.TrueEqualsString(obj.Link) && - this.LockedDate.TrueEquals(obj.LockedDate) && - this.QuestionId.TrueEquals(obj.QuestionId) && - this.Score.TrueEquals(obj.Score) && - this.ShareLink.TrueEqualsString(obj.ShareLink) && - this.Tags.TrueEqualsString(obj.Tags) && - this.Title.TrueEqualsString(obj.Title) && - this.UpVoteCount.TrueEquals(obj.UpVoteCount) && - this.Upvoted.TrueEquals(obj.Upvoted); - } - - public bool EqualsDynamic(dynamic obj) - { - return - this.Accepted.TrueEquals((bool)obj.accepted) && - this.AnswerId.TrueEquals((int)obj.answer_id) && - this.Body.TrueEqualsString((string)obj.body) && - this.BodyMarkdown.TrueEqualsString((string)obj.body_markdown) && - this.CommentCount.TrueEquals((int)obj.comment_count) && - this.Comments.TrueEqualsListDynamic((IEnumerable)obj.comments) && - this.CommunityOwnedDate.TrueEquals((DateTime)obj.community_owned_date) && - this.CreationDate.TrueEquals((DateTime)obj.creation_date) && - this.DownVoteCount.TrueEquals((int)obj.down_vote_count) && - this.Downvoted.TrueEquals((bool)obj.downvoted) && - this.IsAccepted.TrueEquals((bool)obj.is_accepted) && - this.LastActivityDate.TrueEquals((DateTime)obj.last_activity_date) && - this.LastEditDate.TrueEquals((DateTime)obj.last_edit_date) && - this.Link.TrueEqualsString((string)obj.link) && - this.LockedDate.TrueEquals((DateTime)obj.locked_date) && - this.QuestionId.TrueEquals((int)obj.question_id) && - this.Score.TrueEquals((int)obj.score) && - this.ShareLink.TrueEqualsString((string)obj.share_link) && - this.Tags.TrueEqualsString((IEnumerable)obj.tags) && - this.Title.TrueEqualsString((string)obj.title) && - this.UpVoteCount.TrueEquals((int)obj.up_vote_count) && - this.Upvoted.TrueEquals((bool)obj.upvoted); - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Models/Badge.cs b/src/Nino.Benchmark/Serialization/Models/Badge.cs deleted file mode 100644 index 4cc002f..0000000 --- a/src/Nino.Benchmark/Serialization/Models/Badge.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using ProtoBuf; -using MessagePack; -using Nino.Core; - -#pragma warning disable 8618 - -namespace Nino.Benchmark.Models -{ - [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, MessagePackObject] - [NinoType] - public partial class Badge : IGenericEquality - { - [System.Runtime.Serialization.DataMember, ProtoMember(1), Key(1 - 1), NinoMember(0)] - public int BadgeId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(3), Key(3 - 1), NinoMember(2)] - public string Name { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(4), Key(4 - 1), NinoMember(3)] - public string Description { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(5), Key(5 - 1), NinoMember(4)] - public int AwardCount { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(8), Key(8 - 1), NinoMember(6)] - public string Link { get; set; } - - public bool Equals(Badge obj) - { - return - this.AwardCount.TrueEquals(obj.AwardCount) && - this.BadgeId.TrueEquals(obj.BadgeId) && - this.Description.TrueEqualsString(obj.Description) && - this.Link.TrueEqualsString(obj.Link) && - this.Name.TrueEqualsString(obj.Name); - } - - public bool EqualsDynamic(dynamic obj) - { - return - this.AwardCount.TrueEquals((int)obj.award_count) && - this.BadgeId.TrueEquals((int)obj.badge_id) && - this.Description.TrueEqualsString((string)obj.description) && - this.Link.TrueEqualsString((string)obj.link) && - this.Name.TrueEqualsString((string)obj.name); - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Models/Comment.cs b/src/Nino.Benchmark/Serialization/Models/Comment.cs deleted file mode 100644 index b5e0410..0000000 --- a/src/Nino.Benchmark/Serialization/Models/Comment.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable IDE1006 -#pragma warning disable SA1516 - -using System; -using MessagePack; -using Nino.Core; -using ProtoBuf; -#pragma warning disable 8618 - -namespace Nino.Benchmark.Models -{ - [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, MessagePackObject] - [NinoType] - public partial class Comment : IGenericEquality - { - [System.Runtime.Serialization.DataMember, ProtoMember(1), Key(1 - 1), NinoMember(0)] - public int CommentId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(2), Key(2 - 1), NinoMember(1)] - public int PostId { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(3), Key(3 - 1), NinoMember(2)] - public DateTime CreationDate { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(5), Key(5 - 1), NinoMember(4)] - public int Score { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(6), Key(6 - 1), NinoMember(5)] - public bool Edited { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(7), Key(7 - 1), NinoMember(6)] - public string Body { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(10), Key(10 - 1), NinoMember(7)] - public string Link { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(11), Key(11 - 1), NinoMember(8)] - public string BodyMarkdown { get; set; } - - [System.Runtime.Serialization.DataMember, ProtoMember(12), Key(12 - 1), NinoMember(9)] - public bool Upvoted { get; set; } - - public bool Equals(Comment obj) - { - return - this.Body.TrueEqualsString(obj.Body) && - this.BodyMarkdown.TrueEqualsString(obj.BodyMarkdown) && - this.CommentId.TrueEquals(obj.CommentId) && - this.CreationDate.TrueEquals(obj.CreationDate) && - this.Edited.TrueEquals(obj.Edited) && - this.Link.TrueEqualsString(obj.Link) && - this.PostId.TrueEquals(obj.PostId) && - this.Score.TrueEquals(obj.Score) && - this.Upvoted.TrueEquals(obj.Upvoted); - } - - public bool EqualsDynamic(dynamic obj) - { - return - this.Body.TrueEqualsString((string)obj.body) && - this.BodyMarkdown.TrueEqualsString((string)obj.body_markdown) && - this.CommentId.TrueEquals((int)obj.comment_id) && - this.CreationDate.TrueEquals((DateTime)obj.creation_date) && - this.Edited.TrueEquals((bool)obj.edited) && - this.Link.TrueEqualsString((string)obj.link) && - this.PostId.TrueEquals((int)obj.post_id) && - this.Score.TrueEquals((int)obj.score) && - this.Upvoted.TrueEquals((bool)obj.upvoted); - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Models/Data.cs b/src/Nino.Benchmark/Serialization/Models/Data.cs deleted file mode 100644 index a2474cb..0000000 --- a/src/Nino.Benchmark/Serialization/Models/Data.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using ProtoBuf; -using MessagePack; -using Nino.Core; - -namespace Nino.Benchmark.Models -{ - - [Serializable] - [ProtoContract] - [NinoType] - [MessagePackObject] - [System.Runtime.Serialization.DataContract] - public partial struct Data - { - [ProtoMember(1)] - [NinoMember(1)] - [Key(1)] - [System.Runtime.Serialization.DataMember] - public int X; - - [ProtoMember(2)] - [NinoMember(2)] - [Key(2)] - [System.Runtime.Serialization.DataMember] - public short Y; - - [ProtoMember(3)] - [NinoMember(3)] - [Key(3)] - [System.Runtime.Serialization.DataMember] - public long Z; - - [ProtoMember(4)] - [NinoMember(4)] - [Key(4)] - [System.Runtime.Serialization.DataMember] - public float F; - - [ProtoMember(5)] - [NinoMember(5)] - [Key(5)] - [System.Runtime.Serialization.DataMember] - public decimal D; - - [ProtoMember(6)] - [NinoMember(6)] - [Key(6)] - [System.Runtime.Serialization.DataMember] - public double Db; - - [ProtoMember(7)] - [NinoMember(7)] - [Key(7)] - [System.Runtime.Serialization.DataMember] - public bool Bo; - - [ProtoMember(8)] - [NinoMember(8)] - [Key(8)] - [ProtoEnum] - [System.Runtime.Serialization.EnumMember] - public TestEnum En; - - public override string ToString() - { - return $"{X},{Y},{Z},{F},{D},{Db},{Bo},{En}"; - } - } - - [Serializable] - [ProtoContract] - [System.Runtime.Serialization.DataContract] - public enum TestEnum : byte - { - A = 1, - B = 2 - } - - [Serializable] - [ProtoContract] - [NinoType] - [MessagePackObject] - [System.Runtime.Serialization.DataContract] - public partial class NestedData - { - [ProtoMember(1)] - [NinoMember(1)] - [Key(1)] - [System.Runtime.Serialization.DataMember] - public string Name = ""; - - [ProtoMember(2)] [NinoMember(2)] [Key(2)] [System.Runtime.Serialization.DataMember] - public Data[] Ps = Array.Empty(); - - public override string ToString() - { - return $"{Name},{Ps[0]}"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/OdinSerializer.dll b/src/Nino.Benchmark/Serialization/OdinSerializer.dll deleted file mode 100644 index c46f549..0000000 Binary files a/src/Nino.Benchmark/Serialization/OdinSerializer.dll and /dev/null differ diff --git a/src/Nino.Benchmark/Serialization/SerializationBenchmark.cs b/src/Nino.Benchmark/Serialization/SerializationBenchmark.cs deleted file mode 100644 index 0fa88a1..0000000 --- a/src/Nino.Benchmark/Serialization/SerializationBenchmark.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Text; -using Nino.Benchmark.Models; -using Nino.Benchmark.Serializers; -using BenchmarkDotNet.Attributes; -using System.Collections.Generic; - -#pragma warning disable 8618 - -namespace Nino.Benchmark -{ - [Config(typeof(BenchmarkConfig))] - public class SerializationBenchmark - { - [ParamsSource(nameof(Serializers))] public SerializerBase Serializer; - - public IEnumerable Serializers => new SerializerBase[] - { - new MessagePack_Lz4(), - new MessagePack_NoCompression(), - new ProtobufNetSerializer(), - new JsonNetSerializer(), - new BinaryFormatterSerializer(), - new DataContractSerializer(), - new JilSerializer(), - new SpanJsonSerializer(), - new Utf8JsonSerializer(), - new FsPicklerSerializer(), - new CerasSerializer(), - new OdinSerializer_(), - new NinoSerializer(), - }; - - static SerializationBenchmark() - { - //nested data - Data[] dt = new Data[10000]; - for (int i = 0; i < dt.Length; i++) - { - dt[i] = new Data() - { - X = short.MaxValue, - Y = byte.MaxValue, - Z = short.MaxValue, - F = 1234.56789f, - D = 66.66666666m, - Db = 999.999999999999, - Bo = true, - En = TestEnum.A, - }; - } - - NestedDataInput = new NestedData() - { - Name = "Test", - Ps = dt - }; - } - - // primitives - protected static readonly sbyte SByteInput = sbyte.MinValue; - protected static readonly short ShortInput = short.MaxValue; - protected static readonly int IntInput = int.MinValue; - protected static readonly long LongInput = long.MaxValue; - protected static readonly byte ByteInput = byte.MaxValue; - protected static readonly ushort UShortInput = ushort.MaxValue; - protected static readonly uint UIntInput = uint.MinValue; - protected static readonly ulong ULongInput = ulong.MaxValue; - protected static readonly bool BoolInput = false; - protected static readonly string StringInput = GetString(100); - protected static readonly char CharInput = 'a'; - protected static readonly DateTime DateTimeInput = DateTime.Today; - - // models - protected static readonly AccessToken AccessTokenInput = new AccessToken(); - - protected static readonly AccountMerge AccountMergeInput = new AccountMerge(); - - protected static readonly Answer AnswerInput = new Answer(); - - protected static readonly Badge BadgeInput = new Badge(); - - protected static readonly Comment CommentInput = new Comment(); - - protected static NestedData NestedDataInput; - - private byte[] _sByteOutput; - private byte[] _shortOutput; - private byte[] _intOutput; - private byte[] _longOutput; - private byte[] _byteOutput; - private byte[] _uShortOutput; - private byte[] _uIntOutput; - private byte[] _uLongOutput; - private byte[] _boolOutput; - private byte[] _stringOutput; - private byte[] _charOutput; - private byte[] _dateTimeOutput; - - private byte[] _accessTokenOutput; - private byte[] _accountMergeOutput; - private byte[] _answerOutput; - private byte[] _badgeOutput; - private byte[] _commentOutput; - private byte[] _nestedDataOutput; - - [GlobalSetup] - public void Setup() - { - // primitives - this._sByteOutput = this.Serializer.Serialize(SByteInput); - this._shortOutput = this.Serializer.Serialize(ShortInput); - this._intOutput = this.Serializer.Serialize(IntInput); - this._longOutput = this.Serializer.Serialize(LongInput); - this._byteOutput = this.Serializer.Serialize(ByteInput); - this._uShortOutput = this.Serializer.Serialize(UShortInput); - this._uIntOutput = this.Serializer.Serialize(UIntInput); - this._uLongOutput = this.Serializer.Serialize(ULongInput); - this._boolOutput = this.Serializer.Serialize(BoolInput); - this._stringOutput = this.Serializer.SerializeString(StringInput); - this._charOutput = this.Serializer.Serialize(CharInput); - this._dateTimeOutput = this.Serializer.Serialize(DateTimeInput); - - // models - this._accessTokenOutput = this.Serializer.SerializeAccessToken(AccessTokenInput); - this._accountMergeOutput = this.Serializer.SerializeAccountMerge(AccountMergeInput); - this._answerOutput = this.Serializer.SerializeAnswer(AnswerInput); - this._badgeOutput = this.Serializer.SerializeBadge(BadgeInput); - this._commentOutput = this.Serializer.SerializeComment(CommentInput); - this._nestedDataOutput = this.Serializer.SerializeNestedData(NestedDataInput); - } - - private static string GetString(int len) - { - StringBuilder sb = new StringBuilder(); - sb.Append('a', len); - return sb.ToString(); - } - - // Serialize - - [Benchmark] - public byte[] _PrimitiveSByteSerialize() => this.Serializer.Serialize(SByteInput); - - [Benchmark] - public byte[] _PrimitiveShortSerialize() => this.Serializer.Serialize(ShortInput); - - [Benchmark] - public byte[] _PrimitiveIntSerialize() => this.Serializer.Serialize(IntInput); - - [Benchmark] - public byte[] _PrimitiveLongSerialize() => this.Serializer.Serialize(LongInput); - - [Benchmark] - public byte[] _PrimitiveByteSerialize() => this.Serializer.Serialize(ByteInput); - - [Benchmark] - public byte[] _PrimitiveUShortSerialize() => this.Serializer.Serialize(UShortInput); - - [Benchmark] - public byte[] _PrimitiveUIntSerialize() => this.Serializer.Serialize(UIntInput); - - [Benchmark] - public byte[] _PrimitiveULongSerialize() => this.Serializer.Serialize(ULongInput); - - [Benchmark] - public byte[] _PrimitiveBoolSerialize() => this.Serializer.Serialize(BoolInput); - - [Benchmark] - public byte[] _PrimitiveStringSerialize() => this.Serializer.SerializeString(StringInput); - - [Benchmark] - public byte[] _PrimitiveCharSerialize() => this.Serializer.Serialize(CharInput); - - [Benchmark] - public byte[] _PrimitiveDateTimeSerialize() => this.Serializer.Serialize(DateTimeInput); - - [Benchmark] - public byte[] AccessTokenSerialize() => this.Serializer.SerializeAccessToken(AccessTokenInput); - - [Benchmark] - public byte[] AccountMergeSerialize() => this.Serializer.SerializeAccountMerge(AccountMergeInput); - - [Benchmark] - public byte[] AnswerSerialize() => this.Serializer.SerializeAnswer(AnswerInput); - - [Benchmark] - public byte[] BadgeSerialize() => this.Serializer.SerializeBadge(BadgeInput); - - [Benchmark] - public byte[] CommentSerialize() => this.Serializer.SerializeComment(CommentInput); - - [Benchmark] - public byte[] NestedDataSerialize() => this.Serializer.SerializeNestedData(NestedDataInput); - - // Deserialize - - [Benchmark] - public SByte _PrimitiveSByteDeserialize() => this.Serializer.Deserialize(this._sByteOutput); - - [Benchmark] - public short _PrimitiveShortDeserialize() => this.Serializer.Deserialize(this._shortOutput); - - [Benchmark] - public Int32 _PrimitiveIntDeserialize() => this.Serializer.Deserialize(this._intOutput); - - [Benchmark] - public Int64 _PrimitiveLongDeserialize() => this.Serializer.Deserialize(this._longOutput); - - [Benchmark] - public Byte _PrimitiveByteDeserialize() => this.Serializer.Deserialize(this._byteOutput); - - [Benchmark] - public ushort _PrimitiveUShortDeserialize() => this.Serializer.Deserialize(this._uShortOutput); - - [Benchmark] - public uint _PrimitiveUIntDeserialize() => this.Serializer.Deserialize(this._uIntOutput); - - [Benchmark] - public ulong _PrimitiveULongDeserialize() => this.Serializer.Deserialize(this._uLongOutput); - - [Benchmark] - public bool _PrimitiveBoolDeserialize() => this.Serializer.Deserialize(this._boolOutput); - - [Benchmark] - public String _PrimitiveStringDeserialize() => this.Serializer.DeserializeString(this._stringOutput); - - [Benchmark] - public Char _PrimitiveCharDeserialize() => this.Serializer.Deserialize(this._charOutput); - - [Benchmark] - public DateTime _PrimitiveDateTimeDeserialize() => this.Serializer.Deserialize(this._dateTimeOutput); - - [Benchmark] - public AccessToken AccessTokenDeserialize() => this.Serializer.DeserializeAccessToken(this._accessTokenOutput); - - [Benchmark] - public AccountMerge AccountMergeDeserialize() => - this.Serializer.DeserializeAccountMerge(this._accountMergeOutput); - - [Benchmark] - public Answer AnswerDeserialize() => this.Serializer.DeserializeAnswer(this._answerOutput); - - [Benchmark] - public Badge BadgeDeserialize() => this.Serializer.DeserializeBadge(this._badgeOutput); - - [Benchmark] - public Comment CommentDeserialize() => this.Serializer.DeserializeComment(this._commentOutput); - - [Benchmark] - public NestedData NestedDataDeserialize() => this.Serializer.DeserializeNestedData(this._nestedDataOutput); - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/BinaryFormatterSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/BinaryFormatterSerializer.cs deleted file mode 100644 index bfd912c..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/BinaryFormatterSerializer.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Runtime.Serialization.Formatters.Binary; -using Nino.Benchmark.Models; - -#pragma warning disable 618 -#pragma warning disable 8604 -// #pragma warning disable 618 - -namespace Nino.Benchmark.Serializers -{ - public class BinaryFormatterSerializer : SerializerBase - { - public T Deserialize(object input) - { - using (var ms = new MemoryStream((byte[])input)) - { - BinaryFormatter formatter = new BinaryFormatter(); - return (T)formatter.Deserialize(ms); - } - } - - public byte[] SerializeImpl(T input) - { - using (var ms = new MemoryStream()) - { - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Serialize(ms, input); - return ms.ToArray(); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return Deserialize(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return Deserialize(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override T Deserialize(byte[] data) - { - using (var ms = new MemoryStream(data)) - { - BinaryFormatter formatter = new BinaryFormatter(); - return (T)formatter.Deserialize(ms); - } - } - - public override string ToString() - { - return "BinaryFormatter"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/CerasSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/CerasSerializer.cs deleted file mode 100644 index eb6508d..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/CerasSerializer.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class CerasSerializer : SerializerBase - { - private Ceras.CerasSerializer ceras = new Ceras.CerasSerializer(); - - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - return ceras.Deserialize(input); - } - - public byte[] SerializeImpl(T input) - { - return ceras.Serialize(input); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "Ceras"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/DataContractSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/DataContractSerializer.cs deleted file mode 100644 index 2677ecd..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/DataContractSerializer.cs +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class DataContractSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - using (var ms = new MemoryStream(input)) - { - var obj = new System.Runtime.Serialization.DataContractSerializer(typeof(T)).ReadObject(ms); - if (obj is null) - { - return Activator.CreateInstance(); - } - - return (T)obj; - } - } - - public byte[] SerializeImpl(T input) - { - using (var ms = new MemoryStream()) - { - new System.Runtime.Serialization.DataContractSerializer(typeof(T)).WriteObject(ms, input); - ms.Flush(); - return ms.ToArray(); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "DataContract"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/FsPicklerSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/FsPicklerSerializer.cs deleted file mode 100644 index 9794b8b..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/FsPicklerSerializer.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using MBrace.FsPickler; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class FsPicklerSerializer : SerializerBase - { - private static readonly BinarySerializer Serializer = MBrace.FsPickler.FsPickler.CreateBinarySerializer(); - - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - using (var ms = new MemoryStream((byte[])input)) - { - return Serializer.Deserialize(ms); - } - } - - public byte[] SerializeImpl(T input) - { - using (var ms = new MemoryStream()) - { - Serializer.Serialize(ms, input); - ms.Flush(); - return ms.ToArray(); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "FsPickler"; - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Serializers/JilSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/JilSerializer.cs deleted file mode 100644 index 5745719..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/JilSerializer.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Text; -using Jil; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class JilSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - return Jil.JSON.Deserialize(Encoding.UTF8.GetString((byte[])input), Options.ISO8601); - } - - public byte[] SerializeImpl(T input) - { - return Encoding.UTF8.GetBytes(Jil.JSON.Serialize(input, Options.ISO8601)); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "Jil"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/JsonNetSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/JsonNetSerializer.cs deleted file mode 100644 index 334a973..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/JsonNetSerializer.cs +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Text; -using Newtonsoft.Json; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class JsonNetSerializer : SerializerBase - { - private static readonly JsonSerializer Serializer = new JsonSerializer(); - - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - using (var ms = new MemoryStream((byte[])input)) - using (var sr = new StreamReader(ms, Encoding.UTF8)) - using (var jr = new JsonTextReader(sr)) - { - return Serializer.Deserialize(jr) ?? Activator.CreateInstance(); - } - } - - public byte[] SerializeImpl(T input) - { - using (var ms = new MemoryStream()) - { - using (var sw = new StreamWriter(ms, Encoding.UTF8)) - using (var jw = new JsonTextWriter(sw)) - { - Serializer.Serialize(jw, input); - } - - ms.Flush(); - return ms.ToArray(); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "JsonNet"; - } - } -} diff --git a/src/Nino.Benchmark/Serialization/Serializers/MessagePackSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/MessagePackSerializer.cs deleted file mode 100644 index 5c565ac..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/MessagePackSerializer.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable SA1649 // File name should match first type name - -using System; -using System.IO; -using System.Text; -using MessagePack; -using Newtonsoft.Json; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class MessagePack_Lz4 : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4Block); - return MessagePack.MessagePackSerializer.Deserialize((byte[])input, lz4Options); - } - - public byte[] SerializeImpl(T input) - { - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4Block); - return MessagePack.MessagePackSerializer.Serialize(input, lz4Options); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "MessagePack_Lz4"; - } - } - - public class MessagePack_NoCompression : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - return MessagePack.MessagePackSerializer.Deserialize((byte[])input); - } - - public byte[] SerializeImpl(T input) - { - return MessagePack.MessagePackSerializer.Serialize(input); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "MessagePack_NoComp"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/NinoSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/NinoSerializer.cs deleted file mode 100644 index 70562e0..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/NinoSerializer.cs +++ /dev/null @@ -1,112 +0,0 @@ -using Nino_Benchmark_Nino; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class NinoSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - Deserializer.Deserialize(input, out T ret); - return ret; - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return token.Serialize(); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - Deserializer.Deserialize(data, out AccessToken token); - return token; - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return merge.Serialize(); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - Deserializer.Deserialize(data, out AccountMerge merge); - return merge; - } - - public override byte[] SerializeAnswer(Answer answer) - { - return answer.Serialize(); - } - - public override Answer DeserializeAnswer(byte[] data) - { - Deserializer.Deserialize(data, out Answer answer); - return answer; - } - - public override byte[] SerializeBadge(Badge badge) - { - return badge.Serialize(); - } - - public override Badge DeserializeBadge(byte[] data) - { - Deserializer.Deserialize(data, out Badge badge); - return badge; - } - - public override byte[] SerializeComment(Comment comment) - { - return comment.Serialize(); - } - - public override Comment DeserializeComment(byte[] data) - { - Deserializer.Deserialize(data, out Comment comment); - return comment; - } - - public override byte[] SerializeData(Data data) - { - return data.Serialize(); - } - - public override Data DeserializeData(byte[] data) - { - Deserializer.Deserialize(data, out Data dt); - return dt; - } - - public override byte[] SerializeString(string str) - { - return str.Serialize(); - } - - public override string DeserializeString(byte[] data) - { - Deserializer.Deserialize(data, out string str); - return str; - } - - public override byte[] SerializeNestedData(NestedData data) - { - return data.Serialize(); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - Deserializer.Deserialize(data, out NestedData dt); - return dt; - } - - public override byte[] Serialize(T input) - { - return input.Serialize(); - } - - public override string ToString() - { - return "Nino"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/OdinSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/OdinSerializer.cs deleted file mode 100644 index 5598138..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/OdinSerializer.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Nino.Benchmark.Models; -using Nino.Benchmark.Serializers; -using OdinSerializer; -using OdinSerializer.Utilities; - -#pragma warning disable SA1649 // File name should match first type name - -public class OdinSerializer_ : SerializerBase -{ - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - using (var ctx = Cache.Claim()) - { - ctx.Value.Config.SerializationPolicy = SerializationPolicies.Everything; - return SerializationUtility.DeserializeValue((byte[])input, DataFormat.Binary, ctx.Value); - } - } - - public byte[] SerializeImpl(T input) - { - using (var ctx = Cache.Claim()) - { - ctx.Value.Config.SerializationPolicy = SerializationPolicies.Everything; - return SerializationUtility.SerializeValue(input, DataFormat.Binary, ctx.Value); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "Odin"; - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/ProtobufNetSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/ProtobufNetSerializer.cs deleted file mode 100644 index 4a1e107..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/ProtobufNetSerializer.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class ProtobufNetSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - using (var ms = new MemoryStream((byte[])input)) - { - return ProtoBuf.Serializer.Deserialize(ms); - } - } - - public byte[] SerializeImpl(T input) - { - - using (var ms = new MemoryStream()) - { - ProtoBuf.Serializer.Serialize(ms, input); - return ms.ToArray(); - } - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "ProtobufNet"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/SerializerBase.cs b/src/Nino.Benchmark/Serialization/Serializers/SerializerBase.cs deleted file mode 100644 index abc7786..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/SerializerBase.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public abstract class SerializerBase - { - public abstract byte[] SerializeAccessToken(AccessToken token); - public abstract AccessToken DeserializeAccessToken(byte[] data); - - public abstract byte[] SerializeAccountMerge(AccountMerge merge); - public abstract AccountMerge DeserializeAccountMerge(byte[] data); - - public abstract byte[] SerializeAnswer(Answer answer); - public abstract Answer DeserializeAnswer(byte[] data); - - public abstract byte[] SerializeBadge(Badge badge); - public abstract Badge DeserializeBadge(byte[] data); - - public abstract byte[] SerializeComment(Comment comment); - public abstract Comment DeserializeComment(byte[] data); - - public abstract byte[] SerializeData(Data data); - public abstract Data DeserializeData(byte[] data); - - public abstract byte[] SerializeString(string str); - public abstract string DeserializeString(byte[] data); - - public abstract byte[] SerializeNestedData(NestedData data); - public abstract NestedData DeserializeNestedData(byte[] data); - - public abstract byte[] Serialize(T input) where T : unmanaged; - public abstract T Deserialize(byte[] data) where T : unmanaged; - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/SpanJsonSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/SpanJsonSerializer.cs deleted file mode 100644 index d7dbc22..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/SpanJsonSerializer.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class SpanJsonSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - return SpanJson.JsonSerializer.Generic.Utf8.Deserialize((byte[])input); - } - - public byte[] SerializeImpl(T input) - { - return SpanJson.JsonSerializer.Generic.Utf8.Serialize(input); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - public override string ToString() - { - return "SpanJson"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/Serialization/Serializers/Utf8JsonSerializer.cs b/src/Nino.Benchmark/Serialization/Serializers/Utf8JsonSerializer.cs deleted file mode 100644 index 9779c0a..0000000 --- a/src/Nino.Benchmark/Serialization/Serializers/Utf8JsonSerializer.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) All contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Nino.Benchmark.Models; - -namespace Nino.Benchmark.Serializers -{ - public class Utf8JsonSerializer : SerializerBase - { - public override T Deserialize(byte[] input) - { - return DeserializeImpl(input); - } - - public T DeserializeImpl(byte[] input) - { - return Utf8Json.JsonSerializer.Deserialize(input); - } - - public byte[] SerializeImpl(T input) - { - return Utf8Json.JsonSerializer.Serialize(input); - } - - public override byte[] SerializeAccessToken(AccessToken token) - { - return SerializeImpl(token); - } - - public override AccessToken DeserializeAccessToken(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAccountMerge(AccountMerge merge) - { - return SerializeImpl(merge); - } - - public override AccountMerge DeserializeAccountMerge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeAnswer(Answer answer) - { - return SerializeImpl(answer); - } - - public override Answer DeserializeAnswer(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeBadge(Badge badge) - { - return SerializeImpl(badge); - } - - public override Badge DeserializeBadge(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeComment(Comment comment) - { - return SerializeImpl(comment); - } - - public override Comment DeserializeComment(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeData(Data data) - { - return SerializeImpl(data); - } - - public override Data DeserializeData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeString(string str) - { - return SerializeImpl(str); - } - - public override string DeserializeString(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] SerializeNestedData(NestedData data) - { - return SerializeImpl(data); - } - - public override NestedData DeserializeNestedData(byte[] data) - { - return DeserializeImpl(data); - } - - public override byte[] Serialize(T input) - { - return SerializeImpl(input); - } - - - public override string ToString() - { - return "UTF8Json"; - } - } -} \ No newline at end of file diff --git a/src/Nino.Benchmark/SimpleTest.cs b/src/Nino.Benchmark/SimpleTest.cs new file mode 100644 index 0000000..a1e8679 --- /dev/null +++ b/src/Nino.Benchmark/SimpleTest.cs @@ -0,0 +1,201 @@ +using System.Linq; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Jobs; +using MemoryPack; +using MessagePack; + +#nullable disable +namespace Nino.Benchmark; + +[CategoriesColumn, MinColumn, MaxColumn, PayloadColumn] +[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] +[SimpleJob(RuntimeMoniker.Net80, warmupCount: 3, iterationCount: 10)] +[MarkdownExporter, AsciiDocExporter, HtmlExporter, CsvExporter, RPlotExporter] +public class SimpleTest +{ + private readonly SimpleClass _simpleClass; + private readonly SimpleClass[] _simpleClasses; + private readonly SimpleStruct _simpleStruct; + private readonly SimpleStruct[] _simpleStructs; + + private readonly byte[][] _serializedSimpleClass; + private readonly byte[][] _serializedSimpleStruct; + private readonly byte[][] _serializedSimpleClasses; + private readonly byte[][] _serializedSimpleStructs; + + public SimpleTest() + { + _simpleClass = SimpleClass.Create(); + _simpleClasses = Enumerable.Range(0, 30).Select(_ => SimpleClass.Create()).ToArray(); + _simpleStruct = SimpleStruct.Create(); + _simpleStructs = Enumerable.Range(0, 30).Select(_ => SimpleStruct.Create()).ToArray(); + + _serializedSimpleClass = new byte[3][]; + _serializedSimpleClass[0] = MessagePackSerializer.Serialize(_simpleClass); + _serializedSimpleClass[1] = MemoryPackSerializer.Serialize(_simpleClass); + _serializedSimpleClass[2] = Nino_Benchmark_Nino.Serializer.Serialize(_simpleClass); + + _serializedSimpleStruct = new byte[3][]; + _serializedSimpleStruct[0] = MessagePackSerializer.Serialize(_simpleStruct); + _serializedSimpleStruct[1] = MemoryPackSerializer.Serialize(_simpleStruct); + _serializedSimpleStruct[2] = Nino_Benchmark_Nino.Serializer.Serialize(_simpleStruct); + + _serializedSimpleClasses = new byte[3][]; + _serializedSimpleClasses[0] = MessagePackSerializer.Serialize(_simpleClasses); + _serializedSimpleClasses[1] = MemoryPackSerializer.Serialize(_simpleClasses); + _serializedSimpleClasses[2] = Nino_Benchmark_Nino.Serializer.Serialize(_simpleClasses); + + _serializedSimpleStructs = new byte[3][]; + _serializedSimpleStructs[0] = MessagePackSerializer.Serialize(_simpleStructs); + _serializedSimpleStructs[1] = MemoryPackSerializer.Serialize(_simpleStructs); + _serializedSimpleStructs[2] = Nino_Benchmark_Nino.Serializer.Serialize(_simpleStructs); + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleClassSerialize")] + public byte[] MessagePackSerializeSimpleClass() + { + return MessagePackSerializer.Serialize(_simpleClass); + } + + [Benchmark, BenchmarkCategory("SimpleClassSerialize")] + public byte[] MemoryPackSerializeSimpleClass() + { + return MemoryPackSerializer.Serialize(_simpleClass); + } + + [Benchmark, BenchmarkCategory("SimpleClassSerialize")] + public byte[] NinoSerializeSimpleClass() + { + return Nino_Benchmark_Nino.Serializer.Serialize(_simpleClass); + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleStructSerialize")] + public byte[] MessagePackSerializeSimpleStruct() + { + return MessagePackSerializer.Serialize(_simpleStruct); + } + + [Benchmark, BenchmarkCategory("SimpleStructSerialize")] + public byte[] MemoryPackSerializeSimpleStruct() + { + return MemoryPackSerializer.Serialize(_simpleStruct); + } + + [Benchmark, BenchmarkCategory("SimpleStructSerialize")] + public byte[] NinoSerializeSimpleStruct() + { + return Nino_Benchmark_Nino.Serializer.Serialize(_simpleStruct); + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleClassesSerialize")] + public byte[] MessagePackSerializeSimpleClasses() + { + return MessagePackSerializer.Serialize(_simpleClasses); + } + + [Benchmark, BenchmarkCategory("SimpleClassesSerialize")] + public byte[] MemoryPackSerializeSimpleClasses() + { + return MemoryPackSerializer.Serialize(_simpleClasses); + } + + [Benchmark, BenchmarkCategory("SimpleClassesSerialize")] + public byte[] NinoSerializeSimpleClasses() + { + return Nino_Benchmark_Nino.Serializer.Serialize(_simpleClasses); + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleStructsSerialize")] + public byte[] MessagePackSerializeSimpleStructs() + { + return MessagePackSerializer.Serialize(_simpleStructs); + } + + [Benchmark, BenchmarkCategory("SimpleStructsSerialize")] + public byte[] MemoryPackSerializeSimpleStructs() + { + return MemoryPackSerializer.Serialize(_simpleStructs); + } + + [Benchmark, BenchmarkCategory("SimpleStructsSerialize")] + public byte[] NinoSerializeSimpleStructs() + { + return Nino_Benchmark_Nino.Serializer.Serialize(_simpleStructs); + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleClassDeserialize")] + public SimpleClass MessagePackDeserializeSimpleClass() + { + return MessagePackSerializer.Deserialize(_serializedSimpleClass[0]); + } + + [Benchmark, BenchmarkCategory("SimpleClassDeserialize")] + public SimpleClass MemoryPackDeserializeSimpleClass() + { + return MemoryPackSerializer.Deserialize(_serializedSimpleClass[1]); + } + + [Benchmark, BenchmarkCategory("SimpleClassDeserialize")] + public SimpleClass NinoDeserializeSimpleClass() + { + Nino_Benchmark_Nino.Deserializer.Deserialize(_serializedSimpleClass[2], out SimpleClass ret); + return ret; + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleStructDeserialize")] + public SimpleStruct MessagePackDeserializeSimpleStruct() + { + return MessagePackSerializer.Deserialize(_serializedSimpleStruct[0]); + } + + [Benchmark, BenchmarkCategory("SimpleStructDeserialize")] + public SimpleStruct MemoryPackDeserializeSimpleStruct() + { + return MemoryPackSerializer.Deserialize(_serializedSimpleStruct[1]); + } + + [Benchmark, BenchmarkCategory("SimpleStructDeserialize")] + public SimpleStruct NinoDeserializeSimpleStruct() + { + Nino_Benchmark_Nino.Deserializer.Deserialize(_serializedSimpleStruct[2], out SimpleStruct ret); + return ret; + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleClassesDeserialize")] + public SimpleClass[] MessagePackDeserializeSimpleClasses() + { + return MessagePackSerializer.Deserialize(_serializedSimpleClasses[0]); + } + + [Benchmark, BenchmarkCategory("SimpleClassesDeserialize")] + public SimpleClass[] MemoryPackDeserializeSimpleClasses() + { + return MemoryPackSerializer.Deserialize(_serializedSimpleClasses[1]); + } + + [Benchmark, BenchmarkCategory("SimpleClassesDeserialize")] + public SimpleClass[] NinoDeserializeSimpleClasses() + { + Nino_Benchmark_Nino.Deserializer.Deserialize(_serializedSimpleClasses[2], out SimpleClass[] ret); + return ret; + } + + [Benchmark(Baseline = true), BenchmarkCategory("SimpleStructsDeserialize")] + public SimpleStruct[] MessagePackDeserializeSimpleStructs() + { + return MessagePackSerializer.Deserialize(_serializedSimpleStructs[0]); + } + + [Benchmark, BenchmarkCategory("SimpleStructsDeserialize")] + public SimpleStruct[] MemoryPackDeserializeSimpleStructs() + { + return MemoryPackSerializer.Deserialize(_serializedSimpleStructs[1]); + } + + [Benchmark, BenchmarkCategory("SimpleStructsDeserialize")] + public SimpleStruct[] NinoDeserializeSimpleStructs() + { + Nino_Benchmark_Nino.Deserializer.Deserialize(_serializedSimpleStructs[2], out SimpleStruct[] ret); + return ret; + } +} \ No newline at end of file diff --git a/src/Nino.Core/Nino.Core.csproj b/src/Nino.Core/Nino.Core.csproj index d6a5f84..6f1e832 100644 --- a/src/Nino.Core/Nino.Core.csproj +++ b/src/Nino.Core/Nino.Core.csproj @@ -8,7 +8,7 @@ 9 Nino.Serialization true - 2.0.1 + 2.0.2 Nino.Serialization JasonXuDeveloper High performance and low size binary serialization solution, especially for Unity. @@ -16,10 +16,8 @@ https://github.com/JasonXuDeveloper/Nino git Nino;Serialization;Binary - Nino.Serialization v2.0.1 -- [Optimisation] More efficient code generated via Source Generator -- [Feature] Polymorphism Solution for Collections Serialization -- [Feature] Support for Unity + Nino.Serialization v2.0.2 +- [Optimisation] More efficient code generation for unmanaged types and arrays MIT diff --git a/src/Nino.Core/Reader.cs b/src/Nino.Core/Reader.cs index 5375afa..93f1a99 100644 --- a/src/Nino.Core/Reader.cs +++ b/src/Nino.Core/Reader.cs @@ -24,41 +24,43 @@ public void Read(out T value) where T : unmanaged public void Read(out T? value) where T : unmanaged { Read(out ushort typeId); - if (typeId == TypeCollector.NullTypeId) + switch (typeId) { - value = null; - return; - } - - if (typeId != TypeCollector.NullableTypeId) - { - throw new InvalidOperationException($"Invalid type id {typeId}"); + case TypeCollector.NullTypeId: + value = null; + return; + case TypeCollector.NullableTypeId: + Read(out T ret); + value = ret; + return; + default: + throw new InvalidOperationException($"Invalid type id {typeId}"); } - - Read(out T ret); - value = ret; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out T[] ret) where T : unmanaged { - ret = null; Read(out ushort typeId); - if (typeId == TypeCollector.NullTypeId) + switch (typeId) { - return; - } - - if (typeId != TypeCollector.CollectionTypeId) - { - throw new InvalidOperationException($"Invalid type id {typeId}"); + case TypeCollector.NullTypeId: + ret = null; + return; + case TypeCollector.CollectionTypeId: + Read(out int length); + _bufferReader.GetBytes(length * sizeof(T), out var bytes); +#if NET5_0_OR_GREATER + ret = GC.AllocateUninitializedArray(length); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref ret[0]), ref MemoryMarshal.GetReference(bytes), + (uint)bytes.Length); +#else + ret = MemoryMarshal.Cast(bytes).ToArray(); +#endif + return; + default: + throw new InvalidOperationException($"Invalid type id {typeId}"); } - - Read(out int length); - ret = new T[length]; - var span = ret.AsSpan(); - _bufferReader.GetBytes(length * sizeof(T), out var bytes); - MemoryMarshal.Cast(bytes).CopyTo(span); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -66,32 +68,32 @@ public void Read(out T?[] ret) where T : unmanaged { ret = null; Read(out ushort typeId); - if (typeId == TypeCollector.NullTypeId) - { - return; - } - - if (typeId != TypeCollector.CollectionTypeId) - { - throw new InvalidOperationException($"Invalid type id {typeId}"); - } - - Read(out int length); - ret = new T?[length]; - for (int i = 0; i < length; i++) + switch (typeId) { - Read(out T? item); - ret[i] = item; + case TypeCollector.NullTypeId: + return; + case TypeCollector.CollectionTypeId: + Read(out int length); + ret = new T?[length]; + for (int i = 0; i < length; i++) + { + Read(out T? item); + ret[i] = item; + } + + return; + default: + throw new InvalidOperationException($"Invalid type id {typeId}"); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out List ret) where T : unmanaged { - ret = null; Read(out T[] arr); if (arr == null) { + ret = null; return; } @@ -104,7 +106,7 @@ public void Read(out IList ret) where T : unmanaged Read(out List list); ret = list; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out ICollection ret) where T : unmanaged { @@ -115,40 +117,42 @@ public void Read(out ICollection ret) where T : unmanaged [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out Dictionary ret) where TKey : unmanaged where TValue : unmanaged { - ret = null; #if NET5_0_OR_GREATER Read(out KeyValuePair[] arr); if (arr == null) { + ret = null; return; } ret = new Dictionary(arr); #else Read(out ushort typeId); - if (typeId == TypeCollector.NullTypeId) - { - return; - } - - if (typeId != TypeCollector.CollectionTypeId) - { - throw new InvalidOperationException($"Invalid type id {typeId}"); - } - - Read(out int length); - ret = new Dictionary(length); - for (int i = 0; i < length; i++) + switch (typeId) { - Read(out TKey key); - Read(out TValue value); - ret[key] = value; + case TypeCollector.NullTypeId: + ret = null; + return; + case TypeCollector.CollectionTypeId: + Read(out int length); + ret = new Dictionary(length); + for (int i = 0; i < length; i++) + { + Read(out TKey key); + Read(out TValue value); + ret.Add(key, value); + } + + return; + default: + throw new InvalidOperationException($"Invalid type id {typeId}"); } #endif } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(out IDictionary ret) where TKey : unmanaged where TValue : unmanaged + public void Read(out IDictionary ret) + where TKey : unmanaged where TValue : unmanaged { Read(out Dictionary dictionary); ret = dictionary; @@ -157,23 +161,23 @@ public void Read(out IDictionary ret) where TKey : u [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out List ret) where T : unmanaged { - ret = null; Read(out T?[] arr); if (arr == null) { + ret = null; return; } ret = new List(arr); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out IList ret) where T : unmanaged { Read(out List list); ret = list; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out ICollection ret) where T : unmanaged { @@ -190,21 +194,20 @@ public void Read(out bool value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Read(out string ret) { - ret = null; Read(out ushort typeId); - if (typeId == TypeCollector.NullTypeId) + switch (typeId) { - return; + case TypeCollector.NullTypeId: + ret = null; + return; + case TypeCollector.StringTypeId: + Read(out int length); + _bufferReader.GetBytes(length * sizeof(char), out var bytes); + ret = MemoryMarshal.Cast(bytes).ToString(); + return; + default: + throw new InvalidOperationException($"Invalid type id {typeId}"); } - - if (typeId != TypeCollector.StringTypeId) - { - throw new InvalidOperationException($"Invalid type id {typeId}"); - } - - Read(out int length); - _bufferReader.GetBytes(length * sizeof(char), out var bytes); - ret = MemoryMarshal.Cast(bytes).ToString(); } } } \ No newline at end of file diff --git a/src/Nino.Core/SpanBufferReader.cs b/src/Nino.Core/SpanBufferReader.cs index 58ac262..b89000e 100644 --- a/src/Nino.Core/SpanBufferReader.cs +++ b/src/Nino.Core/SpanBufferReader.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Nino.Core @@ -16,18 +17,21 @@ public SpanBufferReader(ReadOnlySpan data) this.data = data; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Get(out T value) where T : unmanaged { - value = MemoryMarshal.Read(data); + value = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(data)); data = data.Slice(sizeof(T)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Get(out bool value) { value = data[0] != 0; data = data.Slice(1); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void GetBytes(int length, out ReadOnlySpan bytes) { bytes = data.Slice(0, length); diff --git a/src/Nino.Core/TypeCollector.cs b/src/Nino.Core/TypeCollector.cs index 7d133d5..3747047 100644 --- a/src/Nino.Core/TypeCollector.cs +++ b/src/Nino.Core/TypeCollector.cs @@ -2,9 +2,9 @@ namespace Nino.Core { public abstract class TypeCollector { - public const int NullTypeId = 0; - public const int StringTypeId = 1; - public const int CollectionTypeId = 2; - public const int NullableTypeId = 3; + public const ushort NullTypeId = 0; + public const ushort StringTypeId = 1; + public const ushort CollectionTypeId = 2; + public const ushort NullableTypeId = 3; } } \ No newline at end of file diff --git a/src/Nino.Core/Writer.cs b/src/Nino.Core/Writer.cs index 03a7fc4..e457807 100644 --- a/src/Nino.Core/Writer.cs +++ b/src/Nino.Core/Writer.cs @@ -6,7 +6,7 @@ namespace Nino.Core { - public readonly unsafe ref struct Writer + public readonly ref struct Writer { private readonly IBufferWriter _bufferWriter; @@ -23,16 +23,20 @@ public Writer(IBufferWriter bufferWriter) #endif } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(byte value) + { + var span = _bufferWriter.GetSpan(1); + span[0] = value; + _bufferWriter.Advance(1); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(T value) where T : unmanaged { - var span = _bufferWriter.GetSpan(sizeof(T)); -#if NET8_0_OR_GREATER - MemoryMarshal.Write(span, in value); -#else - MemoryMarshal.Write(span, ref value); -#endif - _bufferWriter.Advance(sizeof(T)); + var span = _bufferWriter.GetSpan(Unsafe.SizeOf()); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(span), value); + _bufferWriter.Advance(Unsafe.SizeOf()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -40,27 +44,36 @@ public void Write(T? value) where T : unmanaged { if (!value.HasValue) { - Write((ushort)TypeCollector.NullTypeId); + Write(TypeCollector.NullTypeId); return; } - Write((ushort)TypeCollector.NullableTypeId); + Write(TypeCollector.NullableTypeId); Write(value.Value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(T[] value) where T : unmanaged + { + Write((Span)value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(Span value) where T : unmanaged { if (value == null) { - Write((ushort)TypeCollector.NullTypeId); + Write(TypeCollector.NullTypeId); return; } - Write((ushort)TypeCollector.CollectionTypeId); - Write(value.Length); - MemoryMarshal.Cast(value).CopyTo(_bufferWriter.GetSpan(value.Length * sizeof(T))); - _bufferWriter.Advance(value.Length * sizeof(T)); + int byteLength = value.Length * Unsafe.SizeOf(); + var span = _bufferWriter.GetSpan(sizeof(ushort) + sizeof(int) + byteLength); + Unsafe.WriteUnaligned(ref span[0], TypeCollector.CollectionTypeId); + Unsafe.WriteUnaligned(ref span[2], value.Length); + Unsafe.CopyBlockUnaligned(ref span[6], ref Unsafe.As(ref value[0]), + (uint)byteLength); + _bufferWriter.Advance(sizeof(ushort) + sizeof(int) + byteLength); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -68,11 +81,11 @@ public void Write(Span value) where T : unmanaged { if (value == null) { - Write((ushort)TypeCollector.NullTypeId); + Write(TypeCollector.NullTypeId); return; } - Write((ushort)TypeCollector.CollectionTypeId); + Write(TypeCollector.CollectionTypeId); Write(value.Length); foreach (var item in value) { @@ -86,7 +99,7 @@ public void Write(List value) where T : unmanaged #if NET6_0_OR_GREATER Write(CollectionsMarshal.AsSpan(value)); #else - Write((IList)value); + Write((ICollection)value); #endif } @@ -96,7 +109,7 @@ public void Write(List value) where T : unmanaged #if NET6_0_OR_GREATER Write(CollectionsMarshal.AsSpan(value)); #else - Write((IList)value); + Write((ICollection)value); #endif } @@ -105,16 +118,22 @@ public void Write(ICollection value) where T : unmanaged { if (value == null) { - Write((ushort)TypeCollector.NullTypeId); + Write(TypeCollector.NullTypeId); return; } - Write((ushort)TypeCollector.CollectionTypeId); - Write(value.Count); + int byteLength = value.Count * Unsafe.SizeOf(); + var span = _bufferWriter.GetSpan(sizeof(ushort) + sizeof(int) + byteLength); + Unsafe.WriteUnaligned(ref span[0], TypeCollector.CollectionTypeId); + Unsafe.WriteUnaligned(ref span[2], value.Count); + var current = span.Slice(6); foreach (var item in value) { - Write(item); + Unsafe.WriteUnaligned(ref current[0], item); + current = current.Slice(Unsafe.SizeOf()); } + + _bufferWriter.Advance(sizeof(ushort) + sizeof(int) + byteLength); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -122,11 +141,11 @@ public void Write(ICollection value) where T : unmanaged { if (value == null) { - Write((ushort)TypeCollector.NullTypeId); + Write(TypeCollector.NullTypeId); return; } - Write((ushort)TypeCollector.CollectionTypeId); + Write(TypeCollector.CollectionTypeId); Write(value.Count); foreach (var item in value) { @@ -137,24 +156,34 @@ public void Write(ICollection value) where T : unmanaged [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Write(bool value) { - _bufferWriter.GetSpan(1)[0] = *(byte*)&value; - _bufferWriter.Advance(1); + Write((byte)(value ? 1 : 0)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(string value) + public unsafe void Write(string value) { - if (value == null) + switch (value) { - Write((ushort)TypeCollector.NullTypeId); - return; + case null: + Write(TypeCollector.NullTypeId); + return; + case "": + Write(TypeCollector.StringTypeId); + Write(0); + return; + default: + int byteLength = value.Length * Unsafe.SizeOf(); + var span = _bufferWriter.GetSpan(sizeof(ushort) + sizeof(int) + byteLength); + Unsafe.WriteUnaligned(ref span[0], TypeCollector.StringTypeId); + Unsafe.WriteUnaligned(ref span[2], value.Length); + fixed (char* p = value) + { + Unsafe.CopyBlockUnaligned(ref span[6], ref Unsafe.AsRef(p), (uint)byteLength); + } + + _bufferWriter.Advance(sizeof(ushort) + sizeof(int) + byteLength); + break; } - - Write((ushort)TypeCollector.StringTypeId); - Write(value.Length); - Span span = _bufferWriter.GetSpan(value.Length * sizeof(char)); - MemoryMarshal.Cast(value.AsSpan()).CopyTo(span); - _bufferWriter.Advance(value.Length * sizeof(char)); } } } \ No newline at end of file diff --git a/src/Nino.Generator/DeserializerGenerator.cs b/src/Nino.Generator/DeserializerGenerator.cs index d50dad9..de5fbb8 100644 --- a/src/Nino.Generator/DeserializerGenerator.cs +++ b/src/Nino.Generator/DeserializerGenerator.cs @@ -120,56 +120,48 @@ int GetId(string typeFullName) continue; } + + var typeSymbol = compilation.GetTypeByMetadataName(typeFullName); + if (typeSymbol == null) + { + //check if is a nested type + TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m => + string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal)); + if (typeDeclarationSyntax == null) + throw new Exception("typeDeclarationSyntax is null"); + + var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+"); + typeSymbol = compilation.GetTypeByMetadataName(typeFullName2); + if (typeSymbol == null) + throw new Exception("structSymbol is null"); + } + + // check if struct is unmanged + if (typeSymbol.IsUnmanagedType) + { + continue; + } sb.GenerateClassDeserializeMethods(typeFullName); + sb.AppendLine($$""" + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void Deserialize(out {{typeFullName}} value, ref Reader reader) + { + value = default; + reader.Read(out ushort typeId); + + """); // only applicable for reference types bool isReferenceType = model is ClassDeclarationSyntax; if (isReferenceType) { - sb.AppendLine($$""" - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void Deserialize(out {{typeFullName}} value, ref Reader reader) - { - value = null; - reader.Read(out ushort typeId); + sb.AppendLine(""" + if (typeId == TypeCollector.NullTypeId) { return; } - - """); - } - else - { - var structSymbol = compilation.GetTypeByMetadataName(typeFullName); - if (structSymbol == null) - { - //check if is a nested type - TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m => - string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal)); - if (typeDeclarationSyntax == null) - throw new Exception("typeDeclarationSyntax is null"); - - var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+"); - structSymbol = compilation.GetTypeByMetadataName(typeFullName2); - if (structSymbol == null) - throw new Exception("structSymbol is null"); - } - - // check if struct is unmanged - if (structSymbol.IsUnmanagedType) - { - continue; - } - - sb.AppendLine($$""" - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void Deserialize(out {{typeFullName}} value, ref Reader reader) - { - value = default; - reader.Read(out ushort typeId); - """); } diff --git a/src/Nino.Generator/EmbedTypeSerializerGenerator.cs b/src/Nino.Generator/EmbedTypeSerializerGenerator.cs index a18c648..c703838 100644 --- a/src/Nino.Generator/EmbedTypeSerializerGenerator.cs +++ b/src/Nino.Generator/EmbedTypeSerializerGenerator.cs @@ -276,10 +276,10 @@ private static string GenerateCollectionSerialization(string collectionType, str { if (value == null) { - writer.Write((ushort)TypeCollector.NullTypeId); + writer.Write(TypeCollector.NullTypeId); return; } - writer.Write((ushort)TypeCollector.CollectionTypeId); + writer.Write(TypeCollector.CollectionTypeId); writer.Write(value.{{lengthName}}); foreach (var item in value) { @@ -301,10 +301,10 @@ private static void Serialize(this {{typeFullName}}? value, ref Writer writer) { if (!value.HasValue) { - writer.Write((ushort)TypeCollector.NullTypeId); + writer.Write(TypeCollector.NullTypeId); return; } - writer.Write((ushort)TypeCollector.NullableTypeId); + writer.Write(TypeCollector.NullableTypeId); value.Value.Serialize(ref writer); } diff --git a/src/Nino.Generator/Nino.Generator.csproj b/src/Nino.Generator/Nino.Generator.csproj index 9a97eb8..e3fb6ef 100644 --- a/src/Nino.Generator/Nino.Generator.csproj +++ b/src/Nino.Generator/Nino.Generator.csproj @@ -10,7 +10,7 @@ Nino.Generator Nino.Generator true - 2.0.1 + 2.0.2 Nino.Generator JasonXuDeveloper Source Generator for the high performance and low size binary serialization solution, especially for Unity. @@ -18,10 +18,8 @@ https://github.com/JasonXuDeveloper/Nino git Nino;Serialization;Binary;Generator - Nino.Serialization v2.0.1 -- [Optimisation] More efficient code generated via Source Generator -- [Feature] Polymorphism Solution for Collections Serialization -- [Feature] Support for Unity + Nino.Serialization v2.0.2 +- [Optimisation] More efficient code generation for unmanaged types and arrays MIT cs false diff --git a/src/Nino.Generator/NinoTypeHelper.cs b/src/Nino.Generator/NinoTypeHelper.cs index d582e24..968f0b3 100644 --- a/src/Nino.Generator/NinoTypeHelper.cs +++ b/src/Nino.Generator/NinoTypeHelper.cs @@ -22,7 +22,7 @@ public static IncrementalValuesProvider GetNinoTypeModels private static bool IsNinoType(SyntaxNode node) => node is TypeDeclarationSyntax typeDeclarationSyntax && typeDeclarationSyntax.AttributeLists.SelectMany(static al => al.Attributes) - .Any(static a => a.Name.ToString() == "NinoType"); + .Any(static a => a.Name.ToString().EndsWith("NinoType")); public static bool IsNinoType(this ITypeSymbol typeSymbol) { diff --git a/src/Nino.Generator/SerializerGenerator.cs b/src/Nino.Generator/SerializerGenerator.cs index 93fdcb2..107594c 100644 --- a/src/Nino.Generator/SerializerGenerator.cs +++ b/src/Nino.Generator/SerializerGenerator.cs @@ -94,16 +94,13 @@ int GetId(string typeFullName) var sb = new StringBuilder(); - sb.GenerateClassSerializeMethods("T", "", "where T : unmanaged"); sb.GenerateClassSerializeMethods("T?", "", "where T : unmanaged"); sb.GenerateClassSerializeMethods("List", "", "where T : unmanaged"); - sb.GenerateClassSerializeMethods("Span", "", "where T : unmanaged"); sb.GenerateClassSerializeMethods("Dictionary", "", "where TKey : unmanaged where TValue : unmanaged"); sb.GenerateClassSerializeMethods("IDictionary", "", "where TKey : unmanaged where TValue : unmanaged"); sb.GenerateClassSerializeMethods("ICollection", "", "where T : unmanaged"); - sb.GenerateClassSerializeMethods("bool"); sb.GenerateClassSerializeMethods("string"); foreach (var model in models) @@ -122,52 +119,45 @@ int GetId(string typeFullName) continue; } + + var typeSymbol = compilation.GetTypeByMetadataName(typeFullName); + if (typeSymbol == null) + { + //check if is a nested type + TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m => + string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal)); + if (typeDeclarationSyntax == null) + throw new Exception("typeDeclarationSyntax is null"); + + var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+"); + typeSymbol = compilation.GetTypeByMetadataName(typeFullName2); + if (typeSymbol == null) + throw new Exception("structSymbol is null"); + } + + // check if struct is unmanged + if (typeSymbol.IsUnmanagedType) + { + continue; + } sb.GenerateClassSerializeMethods(typeFullName); + sb.AppendLine($" [MethodImpl(MethodImplOptions.AggressiveInlining)]"); + sb.AppendLine( + $" private static void Serialize(this {typeFullName} value, ref Writer writer)"); + sb.AppendLine(" {"); // only applicable for reference types bool isReferenceType = model is ClassDeclarationSyntax; if (isReferenceType) { - sb.AppendLine($" [MethodImpl(MethodImplOptions.AggressiveInlining)]"); - sb.AppendLine( - $" private static void Serialize(this {typeFullName} value, ref Writer writer)"); - sb.AppendLine(" {"); sb.AppendLine(" if (value == null)"); sb.AppendLine(" {"); - sb.AppendLine($" writer.Write((ushort)TypeCollector.NullTypeId);"); + sb.AppendLine($" writer.Write(TypeCollector.NullTypeId);"); sb.AppendLine(" return;"); sb.AppendLine(" }"); sb.AppendLine(); } - else - { - var structSymbol = compilation.GetTypeByMetadataName(typeFullName); - if (structSymbol == null) - { - //check if is a nested type - TypeDeclarationSyntax? typeDeclarationSyntax = models.FirstOrDefault(m => - string.Equals(m.GetTypeFullName(), typeFullName, StringComparison.Ordinal)); - if (typeDeclarationSyntax == null) - throw new Exception("typeDeclarationSyntax is null"); - - var typeFullName2 = typeDeclarationSyntax.GetTypeFullName("+"); - structSymbol = compilation.GetTypeByMetadataName(typeFullName2); - if (structSymbol == null) - throw new Exception("structSymbol is null"); - } - - // check if struct is unmanged - if (structSymbol.IsUnmanagedType) - { - continue; - } - - sb.AppendLine($" [MethodImpl(MethodImplOptions.AggressiveInlining)]"); - sb.AppendLine( - $" private static void Serialize(this {typeFullName} value, ref Writer writer)"); - sb.AppendLine(" {"); - } void WriteMembers(List members, string valName) { @@ -294,8 +284,78 @@ public static void ReturnBufferWriter(ArrayBufferWriter bufferWriter) bufferWriter.Clear(); BufferWriters.Enqueue(bufferWriter); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe byte[] Serialize(this T value) where T : unmanaged + { + byte[] ret = new byte[sizeof(T)]; + Unsafe.WriteUnaligned(ref ret[0], value); + return ret; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(this T value, IBufferWriter bufferWriter) where T : unmanaged + { + Writer writer = new Writer(bufferWriter); + value.Serialize(ref writer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe byte[] Serialize(this T[] value) where T : unmanaged + { + return Serialize((Span)value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(this T[] value, IBufferWriter bufferWriter) where T : unmanaged + { + Writer writer = new Writer(bufferWriter); + value.Serialize(ref writer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe byte[] Serialize(this Span value) where T : unmanaged + { + if (value == null) + return new byte[2]; + int byteLength = value.Length * sizeof(T); + #if NET6_0_OR_GREATER + byte[] ret = GC.AllocateUninitializedArray(byteLength + 6); + #else + byte[] ret = new byte[byteLength + 6]; + #endif + Unsafe.WriteUnaligned(ref ret[0], (ushort)TypeCollector.CollectionTypeId); + Unsafe.WriteUnaligned(ref ret[2], value.Length); + Unsafe.CopyBlockUnaligned(ref ret[6], ref Unsafe.As(ref value[0]), (uint)byteLength); + return ret; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(this Span value, IBufferWriter bufferWriter) where T : unmanaged + { + Writer writer = new Writer(bufferWriter); + value.Serialize(ref writer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe byte[] Serialize(this bool value) + { + if (value) + return new byte[1] { 1 }; + + return new byte[1] { 0 }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Serialize(this bool value, IBufferWriter bufferWriter) + { + Writer writer = new Writer(bufferWriter); + value.Serialize(ref writer); + } {{GeneratePrivateSerializeImplMethodBody("T", " ", "", "where T : unmanaged")}} + + {{GeneratePrivateSerializeImplMethodBody("T[]", " ", "", "where T : unmanaged")}} {{GeneratePrivateSerializeImplMethodBody("List", " ", "", "where T : unmanaged")}} @@ -304,11 +364,9 @@ public static void ReturnBufferWriter(ArrayBufferWriter bufferWriter) {{GeneratePrivateSerializeImplMethodBody("ICollection", " ", "", "where T : unmanaged")}} {{GeneratePrivateSerializeImplMethodBody("T?", " ", "", "where T : unmanaged")}} - + {{GeneratePrivateSerializeImplMethodBody("List", " ", "", "where T : unmanaged")}} - {{GeneratePrivateSerializeImplMethodBody("Span", " ", "", "where T : unmanaged")}} - {{GeneratePrivateSerializeImplMethodBody("ICollection", " ", "", "where T : unmanaged")}} {{GeneratePrivateSerializeImplMethodBody("string", " ")}} diff --git a/src/Nino.UnitTests/IssueTest.cs b/src/Nino.UnitTests/IssueTest.cs index da5855e..7c8a130 100644 --- a/src/Nino.UnitTests/IssueTest.cs +++ b/src/Nino.UnitTests/IssueTest.cs @@ -12,6 +12,66 @@ namespace Nino.UnitTests [SuppressMessage("ReSharper", "SpecifyACultureInStringConversionExplicitly")] public class IssueTest { + [TestClass] + public class InheritanceTest + { + public class PackageBase + { + + } + + [Nino.Core.NinoType] + [Serializable] + public sealed partial class MyPackPerson : PackageBase + { + public int P1 { get; set; } + + public string P2 { get; set; } + + public char P3 { get; set; } + + public double P4 { get; set; } + + public List P5 { get; set; } + + public Dictionary P6 { get; set; } + } + + [Nino.Core.NinoType] + [Serializable] + public sealed partial class MyClassModel : PackageBase + { + public DateTime P1 { get; set; } + } + + [TestMethod] + public void Test() + { + MyPackPerson person = new MyPackPerson + { + P1 = 1, + P2 = "Hello", + P3 = 'A', + P4 = 3.14, + P5 = new List { 1, 2, 3 }, + P6 = new Dictionary + { + { 1, new MyClassModel { P1 = DateTime.Now } } + } + }; + var bytes = person.Serialize(); + Deserializer.Deserialize(bytes, out MyPackPerson person2); + Assert.AreEqual(person.P1, person2.P1); + Assert.AreEqual(person.P2, person2.P2); + Assert.AreEqual(person.P3, person2.P3); + Assert.AreEqual(person.P4, person2.P4); + Assert.AreEqual(person.P5.Count, person2.P5.Count); + Assert.AreEqual(person.P6.Count, person2.P6.Count); + Assert.AreEqual(person.P6[1].P1, person2.P6[1].P1); + } + } + + [TestClass] public class IssueIgnore { diff --git a/src/Nino/Nino.csproj b/src/Nino/Nino.csproj index e9fb7eb..0db2777 100644 --- a/src/Nino/Nino.csproj +++ b/src/Nino/Nino.csproj @@ -7,7 +7,7 @@ true Nino true - 2.0.1 + 2.0.2 Nino JasonXuDeveloper High performance and low size binary serialization solution, especially for Unity. @@ -15,10 +15,8 @@ https://github.com/JasonXuDeveloper/Nino git Nino;Serialization;Binary - Nino.Serialization v2.0.1 -- [Optimisation] More efficient code generated via Source Generator -- [Feature] Polymorphism Solution for Collections Serialization -- [Feature] Support for Unity + Nino.Serialization v2.0.2 +- [Optimisation] More efficient code generation for unmanaged types and arrays MIT