当前位置: 首页 > news >正文

Unity 二进制读写小框架

文章目录

    • 前言
    • 框架获取与集成
    • 使用方法
      • 基本配置
      • 自动生成序列化方法
    • 实战示例
    • 技术原理与优势
      • 二进制序列化的优势
      • SJBinary的设计特点
    • 最佳实践建议
    • 适用场景
    • 总结

前言

在Unity开发过程中,与后台交互时经常需要处理大型数据文件。当遇到一个近2MB的本地JSON文件需要解析为对象时,使用传统的JSON解析方案(无论是Unity自带的JsonUtility还是流行的Newtonsoft Json.NET)都面临着显著的性能瓶颈。在实测中,这些方案解析时间可能长达3秒以上,即使经过优化也需要约1.5秒,同时还伴随着大量的GC(垃圾回收)开销。

针对这一问题,我们开发了一个高性能的二进制序列化框架——SJBinary。经过测试,该框架在性能表现上超越了市面上多数JSON框架和Unity自带的BinaryFormatter,接近Protobuf-net的性能水平,虽然略低于MessagePack,但其集成简单、代码量小的特点使其成为Unity项目中数据序列化的优秀选择。

实测数据显示,使用SJBinary创建10万个对象并序列化为二进制数据仅需480多毫秒,反序列化过程仅需340多毫秒,性能提升显著。
提示:二进制数据处理本质上比JSON处理更加高效,因为它避免了文本解析的复杂过程,直接使用二进制格式表示数据。

框架获取与集成

sjgenerate下载链接
1.点击上面链接即可下载
2.下载完后将SjBinary拖入项目即可
3.定义类并添加注解[SJBinary]及实现接口ISJSerializable

使用方法

基本配置


[SJBinary]
public class A : ISJSerializable
{public string name;public int age;public void Deserialize(SJBinaryReader reader){throw new System.NotImplementedException();}public void Serialize(SJBinaryWriter writer){throw new System.NotImplementedException();}
}

自动生成序列化方法

  • 点击Unity顶部菜单栏:Tools -> SJBinary -> Generate Methods
  • 系统将自动实现Deserialize和Serialize方法

生成的类结构如下:

[SJBinary]
public class B : ISJSerializable
{public string name;public int age;public void Serialize(SJBinaryWriter writer){writer.Write(this.name);writer.Write(this.age);}public void Deserialize(SJBinaryReader reader){this.name = reader.ReadString();this.age = reader.ReadInt32();}
}

实战示例

以下是一个完整的使用示例,展示了如何在Unity中使用SJBinary进行高效序列化和反序列化:

public class ErJinZhiSample : MonoBehaviour
{//优化前497 343msprivate List<byte[]> serializedData = new List<byte[]>();public List<TestA> deserializedObjects = new List<TestA>();private const int count = 100000;public Button btnLoad;public Button btnCreate;// 复用的 readerprivate SJBinaryReader reader;void Start(){btnLoad.onClick.AddListener(TestLoad);btnCreate.onClick.AddListener(TestCreate);}void TestCreate(){serializedData.Clear();var writer = new SJBinary.SJBinaryWriter(1024); // 可复用缓冲区Stopwatch sw = Stopwatch.StartNew();for (int i = 0; i < count; i++){writer.Reset(); // 复用缓冲区TestA obj = new TestA{age = i,name = $"Name_{i}",time = DateTime.Now.Ticks,actions = "Run,Jump",actionsList = new List<string> { "Run", "Jump", "Walk" },ids = new List<int> { 1, 2, 3 },pads = new List<int> { 10, 20, 30 }};obj.Serialize(writer);// 保存二进制数据(注意这里保存的是 ArraySegment 以避免复制)serializedData.Add(writer.GetBytes());}sw.Stop();UnityEngine.Debug.Log($"[Create] Created and serialized {count} objects in {sw.ElapsedMilliseconds} ms");}void TestLoad(){deserializedObjects.Clear();Stopwatch sw = Stopwatch.StartNew();for (int i = 0; i < count; i++){byte[] data = serializedData[i];// 复用 readerif (reader == null)reader = new SJBinary.SJBinaryReader(data);elsereader.SetBuffer(data, 0, data.Length);TestA obj = new TestA();obj.Deserialize(reader);deserializedObjects.Add(obj);}sw.Stop();UnityEngine.Debug.Log($"[Load] Deserialized {count} objects in {sw.ElapsedMilliseconds} ms");}
}

技术原理与优势

二进制序列化的优势

1.高效性能: 二进制格式避免了文本解析的复杂性,直接读写内存数据
2.紧凑体积: 二进制数据通常比等效的JSON文本小30%-50%
3.低GC开销: 通过缓冲区复用和零拷贝技术大幅减少垃圾回收压力

SJBinary的设计特点

1.简单集成: 只需添加注解和接口实现,无需复杂配置
2.代码生成: 提供工具自动生成序列化代码,减少手动编写错误
3.缓冲区复用: 支持读写缓冲区的复用,极大减少内存分配
4.类型安全: 编译时检查类型一致性,避免运行时错误

最佳实践建议

1.适当初始化缓冲区大小: 根据典型数据大小初始化缓冲区,避免频繁扩容
2.复用读写器实例: 特别是在循环中处理多个对象时
3.处理版本兼容性: 当数据结构变化时,需要考虑向后兼容性策略
4.异常处理: 在序列化和反序列化过程中添加适当的异常处理机制

适用场景

SJBinary特别适用于以下场景:

  • 需要频繁序列化/反序列大量数据的游戏
  • 对性能敏感的网络通信应用
  • 需要持久化大量游戏状态的单机游戏
  • 需要快速加载大型配置文件的应用程序

总结

SJBinary为Unity开发者提供了一个简单易用且高性能的二进制序列化解决方案。通过其简洁的API设计和高效的实现,它能够显著提升数据处理的性能,同时保持较低的内存开销。对于需要处理大量数据的Unity项目,SJBinary是一个值得考虑的轻量级解决方案。

如果您在使用过程中有任何建议或问题,欢迎在评论区留言反馈。我们将持续优化和改进这个框架,以满足更多开发场景的需求。

http://www.dtcms.com/a/342016.html

相关文章:

  • 机器人 - 无人机基础(4) - FreeRTOS
  • MFC随笔—不使用对话框资源模板创建对话框
  • 嵌入式ARM程序高级调试基础:8.QEMU ARM虚拟机与tftp配置
  • QT的项目pro qmake编译
  • OpenCV结构光三维重建类cv::structured_light::GrayCodePattern
  • 01 网络信息内容安全--绪论
  • OpenCV图像色彩空间转换
  • OpenCV图像形态学操作
  • SigNoz 外置 ClickHouse 高可用部署实践
  • Qt二维码生成器项目开发教程 - 从零开始构建专业级QR码生成工具
  • AI + 云原生 + ITSM 的三重融合:企业数字化转型的新引擎
  • Azure官网为何没直接体现专业服务
  • unity之物体旋转
  • 使用 queryParameters:参数,拦截到所有mars3d的网络请求
  • PPIO首发上线DeepSeek-V3.1,Agent 能力大幅提升
  • 驱动-在自定义总线上创建驱动-分析驱动注册流程
  • Linux笔记---策略模式与日志
  • Neovim clangd LSP 配置出现 “attempt to call field ‘ge‘”
  • [论文阅读] 人工智能 + 软件工程 | 当AI成为文学研究员:Agentic DraCor如何用MCP解锁戏剧数据分析
  • 短视频矩阵管理软件推荐:小麦矩阵系统全面解析
  • AR技术:重塑汽车制造的未来
  • B站视频字幕提取-为学习所用
  • java中ReentrantLock使用公平锁相关问题
  • 河南萌新联赛2025第(六)场:郑州大学补题
  • 分享一个基于Python与spark大数据的护肤品市场用户行为分析与可视化平台,基于hadoop的护肤品使用行为追踪与分析可视化平台的设计与实现
  • uniapp vue3 ts自定义底部 tabbar菜单
  • FPGA DP1.4 With DSC解决方案
  • IE启动时主页被360守护了想变回去怎么办?
  • Spring Boot + Spring AI 最小可运行 Demo
  • TensorFlow深度学习实战(33)——深度确定性策略梯度