MessagePackのシリアライズ・デシリアライズ時間がJsonよりが遅くなる
API通信を高速化するためMessagePackを使用したいと考えており
シリアライズ・デシリアライズの速度がどれだけ違うかを
MessagePackとJSONを使用して、
下記処理で速度比較を行っています。
■追記
計測に誤りがあったのでソースコード書き直し、計測値を再計測
シリアライズ後のサイズを追加
データ作成→時間計測→シリアライズ→時間計測→デシリアライズ→時間計測
■使用したMsgPack
https://github.com/msgpack/msgpack-cli/releases
上記URLのバージョン0.62内にあるzipファイルを展開して
unity3dフォルダ内にあるMsgPack.dllを使用しています。
■使用したJson
MiniJSON
■テストケース
1:
(0-10000までのintのListを100回シリアライズ・デシリアライズした平均値)を
Android実機で確認
2:
(0-10000までのstringのListを100回シリアライズ・デシリアライズした平均値)を
Android実機で確認
■テスト結果
■ケース1
MsgPack(Array):
シリアライズ後のバイト数:29747
シリアライズ時間 :24.6msec
デシリアライズ時間:165.2msec
Json:
シリアライズ後のバイト数:48891
シリアライズ時間 :31.1msec
デシリアライズ時間:74.7msec
■ケース2
MsgPack(Array):
シリアライズ後のバイト数:48893
シリアライズ時間 :37.6 msec
デシリアライズ時間:277.0 msec
Json:
シリアライズ後のバイト数:68891
シリアライズ時間 :22.2 msec
デシリアライズ時間:57.5 msec
■ソースコード
using UnityEngine;
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using MiniJSON;
using MsgPack;
using MsgPack.Serialization;
using System.Linq;
public class MsgPackAndJsonCompare : MonoBehaviour {
public int SampleCount = 100;
private string MsgLog = "";
private int SampleIndex = 0;
List<long> ArrayListLong = new List<long>();
List<string> ArrayListString = new List<string>();
/// <summary>
/// intデータ作成処理
/// </summary>
public void OnClickArrayInt()
{
for(int i = 0; i < 10000; i++)
{
ArrayListLong.Add(i);
}
Debug.Log("OnClickArrayInt End");
}
/// <summary>
/// Stringデータ作成処理
/// </summary>
public void OnClickArrayString()
{
for (int i = 0; i < 10000; i++)
{
ArrayListString.Add(i.ToString());
}
Debug.Log("OnClickArrayString End");
}
/// <summary>
/// 100回ループするテスト開始
/// </summary>
/// <param name="sendMode"></param>
public void OnClickCompare(int sendMode)
{
SampleIndex = 0;
for (int i = SampleIndex; i < SampleCount; i++)
{
MsgLog = MsgLog + ",LoopCnt=" + i.ToString();
MsgLog = MsgLog + ",StartTime=" + DateTime.Now.Ticks.ToString();
MainFunc(sendMode);
MsgLog = MsgLog + " ,EndTime=" + DateTime.Now.Ticks.ToString() + "\n";
}
Debug.Log("Function End");
}
/// <summary>
/// メイン処理
/// </summary>
/// <param name="compareMode"></param>
private void MainFunc(int compareMode)
{
// ArrayInt-MsgPack
if (compareMode == 0)
{
MsgLog = MsgLog + ",シリアライズStartTime=" + DateTime.Now.Ticks.ToString();
var stream = new MemoryStream();
// Create serializer instance.
var serializer = MessagePackSerializer.Get<List<long>>();
serializer.Pack(stream, ArrayListLong);
//long datalen = stream.Length;
MsgLog = MsgLog + ",シリアライズEndTime=" + DateTime.Now.Ticks.ToString();
stream.Position = 0;
List<long> deserializedObject = serializer.Unpack(stream);
MsgLog = MsgLog + ",デシリアライズEndTime=" + DateTime.Now.Ticks.ToString();
}
// ArrayInt-Json
else if (compareMode == 1)
{
MsgLog = MsgLog + ",シリアライズStartTime=" + DateTime.Now.Ticks.ToString();
string serialized = Json.Serialize(ArrayListLong);
int ilenb = System.Text.Encoding.GetEncoding(65001).GetByteCount(serialized);
MsgLog = MsgLog + ",シリアライズEndTime=" + DateTime.Now.Ticks.ToString();
List<System.Object> deserializedDoubleList = Json.Deserialize(serialized) as List<System.Object>;
List<long> longList = deserializedDoubleList.OfType<long>().ToList();
MsgLog = MsgLog + ",デシリアライズEndTime=" + DateTime.Now.Ticks.ToString();
}
// ArrayString-MsgPack
else if (compareMode == 2)
{
MsgLog = MsgLog + ",シリアライズStartTime=" + DateTime.Now.Ticks.ToString();
var stream = new MemoryStream();
// Create serializer instance.
var serializer = MessagePackSerializer.Get<List<string>>();
serializer.Pack(stream, ArrayListString);
long datalen = stream.Length;
MsgLog = MsgLog + ",シリアライズEndTime=" + DateTime.Now.Ticks.ToString();
stream.Position = 0;
List<string> deserializedObject = serializer.Unpack(stream);
MsgLog = MsgLog + ",デシリアライズEndTime=" + DateTime.Now.Ticks.ToString();
}
// ArrayString-Json
else if (compareMode == 3)
{
MsgLog = MsgLog + ",シリアライズStartTime=" + DateTime.Now.Ticks.ToString();
string serialized = Json.Serialize(ArrayListString);
int ilenb = System.Text.Encoding.GetEncoding(65001).GetByteCount(serialized);
MsgLog = MsgLog + ",シリアライズEndTime=" + DateTime.Now.Ticks.ToString();
List<System.Object> deserializedDoubleList = Json.Deserialize(serialized) as List<System.Object>;
List<string> longList = deserializedDoubleList.OfType<string>().ToList();
MsgLog = MsgLog + ",デシリアライズEndTime=" + DateTime.Now.Ticks.ToString();
}
}
public void OnclickLog()
{
StartCoroutine(LogDisp());
}
IEnumerator LogDisp()
{
string[] LogArray = MsgLog.Split('\n');
int maxloop = LogArray.Length;
int i = 0;
while (i < maxloop)
{
Debug.Log("Log=" + LogArray[i]);
yield return 0;
i++;
}
}
■問題点
ネットなどで情報を集めているとMessagePackの方が早いという記述が
多くみられるのですが、私のソースではMessagePackで処理するよりも
JSONの方が速度が速いため、やり方が間違っているのではと疑っています。