UNITY Serializer 序列化 横向对比
UNITY Serializer 序列化 横向对比
关于序列化,无论是.net还是unity自身都提供了一定保障。然而人总是吃着碗里想着锅里,跑去github挖个宝是常有的事。看看各家大佬的本事。最有趣的就是每个开源库首页上各个都有吊打隔壁的意思。
测试结果
测试环境
- Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
- 16.0 GB
- Unity 2018.3.9f1 .NET 4.x
- 测试均为Windowns Standalone Release配置
开源库 | 序列化 | 反序列化 | 继承多态 | il2cpp | il2cpp序列化 | il2cpp反序列化 | 需要外加代码或标签 | 高级特性 |
---|---|---|---|---|---|---|---|---|
BinaryFormatter | 80 | 80 | yes | yes | 65 | 58 | no | .NET自带 |
JsonUtility | 16 | 31 | no | yes | 20 | 16 | no | Unity自带 |
OdinSerializer | 22 | 48 | yes | yes | 211 | 244 | no | Unity.Object也能参与序列化 |
MessagePack-CSharp | 1 | 3 | no | no | N/A | N/A | yes | 据说可生通过标记配合模板成代码进行il2cpp |
NetSerializer | 5 | 10 | yes | no | N/A | N/A | yes | MPL协议谨慎 |
Newtonsoft.Json | 25 | 29 | yes | no | N/A | N/A | no |
测试用例
https://github.com/oplusx/UnitySerializerBenchmarks
using MessagePack;
using Newtonsoft.Json;
using OdinSerializer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class test : MonoBehaviour
{
[Serializable]
[MessagePackObject]
public class No1
{
[Key(0)]
public int no1;
[Key(1)]
public string hehe = "hehe";
}
[Serializable]
[MessagePackObject]
public class No2 : No1
{
[Key(0)]
public int no2;
}
[Serializable]
[MessagePackObject]
public class Set
{
[Key(0)]
public List<No1> set = new List<No1>();
}
// Start is called before the first frame update
void Start()
{
var stream = new MemoryStream();
var set = new Set();
for(int i = 0; i < 10; i++)
{
set.set.Add(new No1());
set.set.Add(new No2());
}
List<Type> types = new List<Type>();
types.Add(typeof(No1));
types.Add(typeof(No2));
types.Add(typeof(Set));
var sw = Stopwatch.StartNew();
BinaryFormatter b = new BinaryFormatter();
stream = new MemoryStream();
sw.Restart();
for (int i = 0; i < 1000; i++)
{
stream.Seek(0, SeekOrigin.Begin);
b.Serialize(stream, set);
}
sw.Stop();
Debug.LogFormat("BinaryFormatter Writing {0} ms", sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < 1000; i++)
{
stream.Seek(0, SeekOrigin.Begin);
var newobj = b.Deserialize(stream);
}
sw.Stop();
Debug.LogFormat("BinaryFormatter Reading {0} ms", sw.ElapsedMilliseconds);
}
}
总结
其实在mono环境下的序列化之争,的确有把.net和unity干翻的意思,然而考虑到多平台,特别是il2cpp之后,选择就少了很多,具体还是要根据实际应用场景了。