この記事でのバージョン
Unity 6000.2.6f2
はじめに
以前、JSONと同じように扱えて、より高速かつコンパクトなMessagePackを
Unityに導入する方法と使い方を紹介しました。
![]() |
今回はそのMessagePackをさらに圧縮する方法の紹介です!
![]() |
Messagepackをさらに圧縮
といってもシリアライズ時にオプションを追加するだけです。(デシリアライズも同じオプションを使う)
//シリアライズオプション var lz4 = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); //圧縮してMessagePack化(シリアライズ) var bytesLz4 = MessagePackSerializer.Serialize(data, lz4); //復元(デシリアライズ) var restored = MessagePackSerializer.Deserialize<IntListContainer>(bytesLz4, lz4);
例えば以下のようにただintの配列もってるだけのクラスを、
using System; using System.Collections.Generic; using MessagePack; using UnityEngine; [MessagePackObject, Serializable] public class IntListContainer{ [Key(0)] public List<int> Numbers = new List<int>(); }
大量のintの配列でインスタンス化した後、
それをMessagepack化して非圧縮と圧縮で比較してみると(ついでにJsonも)、
//生成するデータの設定 int elementCount = 500000;//生成する整数の個数 float nonZeroDensity = 0.5f;//0以外を置く確率(小さいほど0が多くなり、圧縮が効きやすい) //整数列を作成 var list = new List<int>(elementCount); for (int i = 0; i < elementCount; i++){ if (Random.value < nonZeroDensity){ list.Add(1 + Random.Range(0, Mathf.Max(1, int.MaxValue))); } else{ list.Add(0); } } var data = new IntListContainer{ Numbers = list }; //圧縮オプション(非圧縮/LZ4) var noComp = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); var lz4 = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); //シリアライズ var bytesJson = System.Text.Encoding.UTF8.GetByteCount(JsonUtility.ToJson(data));//Jsonも比較用に var bytesNo = MessagePackSerializer.Serialize(data, noComp); var bytesLz4 = MessagePackSerializer.Serialize(data, lz4); //見やすいようにMB換算 var mbJson = bytesJson / (1024f * 1024f); var mbNo = bytesNo.Length / (1024f * 1024f); var mbLz4 = bytesLz4.Length / (1024f * 1024f); var rate = 100f * bytesLz4.Length / Mathf.Max(1, bytesNo.Length); //結果出力 Debug.Log("=== MessagePack int配列(LZ4有無) サイズ比較 ==="); Debug.Log($"要素数: {elementCount}, 非ゼロ密度: {nonZeroDensity:P0}"); Debug.Log($"Jsonサイズ : {mbJson:F2} MB"); Debug.Log($"MessagePack 非圧縮サイズ: {mbNo:F2} MB"); Debug.Log($"MessagePack 圧縮サイズ : {mbLz4:F2} MB"); Debug.Log($"圧縮率 : {rate:F1}%(小さいほど良い)"); //一応、復元確認 var restored = MessagePackSerializer.Deserialize<IntListContainer>(bytesLz4, lz4); Debug.Log($"復元確認: Numbers.Count={restored.Numbers.Count}");
圧縮によってサイズが大幅に減少してるのが分かります。
![]() |
ただし、上記のデータは0以外の数字が出る確率(nonZeroDensity)が5%、
同じようなパターンを多く含むデータだったため、ここまで圧縮されています。
逆に0以外が出る確率(nonZeroDensity)が50%という、
同じようなパターンが少ないデータだと、圧縮率が悪くなってしまいます。
![]() |


