最近在研究一個有趣的資料交換格式 —— TOON (Token-Oriented Object Notation)
主打「低 Token 消耗」與「高結構可讀性」
由於目前 TOON 也開始有 .NET 的實作版本(例如
ToonNet 與
ToonSharp)
我就想測試一下它在實際序列化(Serialize)與反序列化(Deserialize)時的表現如何
最後我採用 ToonNet ,原因我最後在說
我用的是一個模擬假資料的模型 SampleData,裡面包含常見欄位像是 Id, Name, Email, Age, Salary ..
並且每筆資料還會有一個小的好友清單 Friends,裡面會有兩筆資料
這次測試使用 Bogus
套件來生成 10,000 筆測試資料,加上好友的大概會有三萬個物件
//建立假資料格式
var fakerZh = new Faker("zh_TW"); // 中文
var faker = new Faker("en")
.RuleFor(x => x.Id, f => Guid.NewGuid()) // Guid
.RuleFor(x => x.Name, f => f.Name.FullName()) // string
.RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.Name)) //Email
.RuleFor(x => x.IsActive, f => f.Random.Bool()) // bool
.RuleFor(x => x.Age, f => f.Random.Int(18, 80)) // int
.RuleFor(x => x.Salary, f => f.Random.Decimal(min: 1.00m, max: 1000.00m)) // decimal
.RuleFor(x => x.Create, f => f.Date.Past(2)) //Datetime
.RuleFor(x => x.Addr, f => fakerZh.Address.FullAddress()) // 中文地址
.RuleFor(x => x.CheineseName, f => fakerZh.Name.LastName() + fakerZh.Name.FirstName());// 中文名稱 中文排版問題,先是FirstName+LastName
for (var i = 1; i <= 5; i++)
{
//Prepare Data
var data = faker.Generate(10_000);
foreach (var d in data) {
d.Friends = faker.Generate(2);
}
//TEST TOON
var sw = Stopwatch.StartNew();
var toonStr = ToonNet.ToonNet.Encode(data);
Console.WriteLine("TOON Length:" + toonStr.Length);
Console.WriteLine(sw.Elapsed);
sw.Restart();
var newToonData = ToonNet.ToonNet.Decode>(toonStr);
Console.WriteLine("TOON Deserialize List Count:" + newToonData.Count());
Console.WriteLine(sw.Elapsed);
Console.WriteLine("--\r\n");
//TEST JSON
var sw1 = Stopwatch.StartNew();
var jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(data);
Console.WriteLine("JSON Length:" + jsonStr.Length);
Console.WriteLine(sw1.Elapsed);
sw1.Restart();
Console.WriteLine("JSON Deserialize List Count:" + Newtonsoft.Json.JsonConvert.DeserializeObject>(jsonStr).Count());
Console.WriteLine(sw1.Elapsed);
Console.WriteLine("==\r\n");
}
這段程式邏輯很單純,就是:
先產生資料;
使用 ToonNet 做序列化與反序列化;
接著使用 JSON (Newtonsoft.Json) 做同樣的動作;
最後印出資料長度與執行時間。
結果:
TOON Length:7347204
00:00:01.6336676
TOON Deserialize List Count:10000
00:00:02.2930853
--
JSON Length:8407197
00:00:00.3537226
JSON Deserialize List Count:10000
00:00:00.6373288
==
TOON Length:7347089
00:00:00.6213259
TOON Deserialize List Count:10000
00:00:01.5129740
--
JSON Length:8407082
00:00:00.1623491
JSON Deserialize List Count:10000
00:00:00.1392289
==
TOON Length:7347134
00:00:00.5848503
TOON Deserialize List Count:10000
00:00:01.6306873
--
JSON Length:8407127
00:00:00.1292341
JSON Deserialize List Count:10000
00:00:00.1408039
==
TOON Length:7347152
00:00:00.5305677
TOON Deserialize List Count:10000
00:00:01.4916888
--
JSON Length:8407145
00:00:00.1151954
JSON Deserialize List Count:10000
00:00:00.1231848
==
TOON Length:7346314
00:00:00.4511246
TOON Deserialize List Count:10000
00:00:01.3426280
--
JSON Length:8406307
00:00:00.1488930
JSON Deserialize List Count:10000
00:00:00.2019341
==
很明顯測試,序列化之後的確文字體積變小了,但是在序列化跟反序列化中速度都不如行之有年的 JSON.net
不過可能隨著之後的進步會有所加速,說一下為何最後我不用 ToonSharp
因為不知道為什麼,在反序列化的過程中
他會一直出現
Unhandled exception. ToonSharp .ToonException: Line 100002: Array count mismatch:
expected 10000 items, got 1
目前看起來無解,網路上查一下也沒有答案,我就換套件測試,當然這不能說 TOON 一定慢於 JSON
畢竟這跟套件的成熟度也會有很大的關係。