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.pswp.cn/news/919801.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919801.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919801.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

?Kubernetes 詳解:云原生時代的容器編排與管理

一 Kubernetes 簡介及部署方法 1.1 應用部署方式演變 在部署應用程序的方式上&#xff0c;主要經歷了三個階段&#xff1a; 傳統部署&#xff1a;互聯網早期&#xff0c;會直接將應用程序部署在物理機上 優點&#xff1a;簡單&#xff0c;不需要其它技術的參與 缺點&#xf…

Kotlin 中的枚舉類 Enum Class

枚舉類在 Kotlin 中是非常強大和靈活的工具,可以用于表示一組固定的常量,并且可以包含屬性、方法、構造函數和伴生對象。它們在處理狀態、選項等場景中非常有用。 1、枚舉類的定義 枚舉類用于創建具有一組數量有限的可能值的類型。 枚舉的每個可能值都稱為“枚舉常量”。每個…

集成電路學習:什么是K-NN最近鄰算法

K-NN:最近鄰算法 K-NN,即K-最近鄰算法(K-Nearest Neighbor algorithm),是一種基本的監督學習算法,廣泛應用于分類和回歸問題中。以下是對K-NN算法的詳細解析: 一、K-NN算法的基本原理 1、K-NN算法的核心思想是: 對于一個新的數據點,算法會在訓練數據集中找到與…

2025最新版mgg格式轉MP3,mflac轉mp3,mgg格式如何轉mp3?

注&#xff1a;需要使用舊版客戶端&#xff0c;并需要禁用更新。使用說明內有鏈接打開軟件&#xff0c;可以選擇將待轉換的歌曲拖入&#xff1b;或者點擊添加將mgg或者mflac歌曲拖入點擊開始轉換等待一會就轉換完成&#xff0c;默認轉換后的歌曲存在桌面的【轉換成功】的文件夾…

嵌入式學習day34-網絡-tcp/udp

day33練習&#xff1a;客戶端 與 服務器實現一個點對點聊天tcp客戶端clifd socketconnect//收 --父進程 //發 --子進程 tcp服務器 listenfd socketbindlistenconnfd accept()//收 -- 父進程 //發 -- 子進程client.c#include "../head.h"int res_fd[1]; // 只需要存…

零知開源——基于STM32F103RBT6與ADXL362三軸加速度計的體感迷宮游戲設計與實現

?零知IDE 是一個真正屬于國人自己的開源軟件平臺&#xff0c;在開發效率上超越了Arduino平臺并且更加容易上手&#xff0c;大大降低了開發難度。零知開源在軟件方面提供了完整的學習教程和豐富示例代碼&#xff0c;讓不懂程序的工程師也能非常輕而易舉的搭建電路來創作產品&am…

《Linux 網絡編程一:網絡編程導論及UDP 服務器的創建與數據接收》

Linux下的網絡編程1. 目的實現不同主機之間進程的通信。2. 問題主機之間在物理層面必須互聯互通。進程之間在軟件層面必須互聯互通。IP地址&#xff1a;計算機的軟件地址&#xff0c;用于標識計算機設備。MAC地址&#xff1a;計算機的硬件地址&#xff08;固定&#xff09;。網…

排序(數據結構)

比較排序 插入排序&#xff08;斗地主摸牌就是一個插入排序&#xff09; 單純的插入排序也叫直接插入排序 時間復雜度&#xff1a; 最好O(n)最壞O(n^2) 過程 先寫單趟&#xff0c;再寫整體 依次比較&#xff0c;如果大于就往后挪動&#xff0c;否則就退出循環&#xff0c;插入數…

【C++組件】Elasticsearch 安裝及使用

&#x1f308; 個人主頁&#xff1a;Zfox_ &#x1f525; 系列專欄&#xff1a;C框架/庫 目錄&#x1f525; 介紹 &#x1f525; ES 安裝 &#x1f98b; 安裝 kibana&#x1f98b; ES 客戶端的安裝&#x1f525; ES 核心概念 &#x1f98b; 索引&#xff08;Index&#xff09;&…

項目:電動車報警器

1.項目需求 點擊遙控器A按鍵&#xff0c;系統進入警戒模式&#xff0c;一旦檢測到震動(小偷偷車)&#xff0c;則喇叭發出聲響報警&#xff0c;嚇退小偷。 點擊遙控器B按鍵&#xff0c;系統退出警戒模式&#xff0c;再怎么搖晃系統都不會報警&#xff0c;否則系統一直發出尖叫&a…

GDSFactory環境配置(PyCharm+Git+KLayout)

1、安裝 PyCharm 和 KLayout 安裝 PyCharm&#xff08;官網社區版即可&#xff09;和 KLayout&#xff08;官網最新版&#xff09;&#xff0c;這兩款軟件均開源&#xff0c;安裝操作簡單&#xff0c;這里不再贅述。&#xff08;注意&#xff1a;PyCharm軟件是否安裝成功以能否…

STM32 定時器(輸出模式)

?? ?一、輸出模式總覽?STM32定時器的輸出比較模式通過比較計數器&#xff08;CNT&#xff09;與捕獲/比較寄存器&#xff08;CCRx&#xff09;的值&#xff0c;控制輸出引腳&#xff08;OCx&#xff09;的電平狀態。六種模式定義如下&#xff1a;?模式宏??觸發動作?&am…

嵌入式硬件篇---手柄

手柄原理&#xff1a;手柄遙控的原理其實可以簡單理解為 “信號的發送與接收”&#xff0c;就像兩個人用對講機聊天&#xff0c;一方說話&#xff08;發送信號&#xff09;&#xff0c;另一方聽話&#xff08;接收信號&#xff09;&#xff0c;然后根據內容行動。下面用通俗的方…

數據庫架構開發知識庫體系

摘要面向初創與企業團隊&#xff0c;系統梳理數據庫與數據平臺從采集、傳輸、存儲、處理、服務化到治理與安全的全鏈路。覆蓋 OLTP/OLAP/HTAP、湖倉一體與實時數據棧&#xff0c;結合國內外工具與方法論&#xff0c;給出架構選型、性能優化、可靠性與合規要點&#xff0c;以及可…

在Excel和WPS表格中合并多個單元格這樣最快

如果要把WPS表格和Excel中多個單元格的數據合成到一個單元格中&#xff0c;不用函數&#xff0c;只需要先寫輸入公式&#xff0c;然后在各個單元格之間輸入&符號即可。&#xff08;當然&#xff0c;&符號不只是連接單元格的數據&#xff0c;也可以直接輸入內容連接&…

在嵌入式上用 C++14實現簡單HSM狀態機

文章目錄概述為什么要遷移到 C&#xff0c;以及 C 的陷阱目標與挑戰為什么不能直接使用 std::function&#xff1f;解決方案&#xff1a;POD 回調與模板 Trampoline核心設計模板 trampoline 實現兩種成員函數綁定策略1. **Per-Transition Context&#xff08;每個狀態轉移綁定一…

【unity】Obfuz加固混淆日志還原解析方案ObfuzResolver

Github | Gitee ObfuzResolver是基于obfuz-tools針對Obfuz的一項輔助工具&#xff0c;方便開發者在unity編輯器中或者運行時快捷將使用Obfuz混淆加固后的日志信息還原為原始信息&#xff0c;以輔助開發者快速定位Bug。 特性 支持unity編輯器模式下還原被加固混淆的日志信息&a…

2025DevOps平臺趨勢解讀:哪些DevOps工具正在引領行業變革?

DevOps平臺已成為企業提升研發效能、實現敏捷交付的核心支柱。2025年DevOps領域正經歷深刻變革&#xff0c;平臺能力正從“工具鏈整合”向“價值流智能中樞”躍升。01. 2025Devops平臺趨勢解讀“全棧式”與“模塊化/可組合”的平衡&#xff1a;企業既需要能覆蓋開發、測試、部署…

第二階段Winform-4:MDI窗口,布局控件,分頁

1_MDI窗口 &#xff08;1&#xff09;MDI是指將多控件窗體在同一窗體中打開,可以設置重疊打開&#xff0c;平捕打開等&#xff0c;MDI窗體&#xff08;Multiple-Document Interface&#xff0c;多文檔界面&#xff09;用于同時顯示多個文檔。在項目中使用MDI窗體時&#xff0c…

實用R語言機器學習指南:從數據預處理到模型實戰(附配套學習資源)

一、為什么需要掌握機器學習建模&#xff1f;在科研與項目實踐中&#xff0c;機器學習已成為數據挖掘的核心工具。本文手把手帶你在R語言中實現7大常用模型&#xff1a;邏輯回歸/正則化回歸決策樹/隨機森林SVM支持向量機XGBoost梯度提升神經網絡全程包含數據標準化→模型訓練→…