[C#] TOON vs JSON:在 .NET 實測序列化效能的真實結果

2025-11-14

最近在研究一個有趣的資料交換格式 —— 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<SampleData>("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());// 中文名稱 中文排版問題&#65292;先是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<List<SampleData>>(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<List<SampleData>>(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 

畢竟這跟套件的成熟度也會有很大的關係。


當麻許的碎念筆記 2014 | Donma Hsu Design.