次のシリアル化ツールが調査に含まれました。
- 単純な文字列連結
- JavaScriptSerializer(.NET Framework)
- DataContractJsonSerializer(.NET Framework 3.5)
- ニュートンJson.net( json.codeplex.com 、james.newtonking.com/ pages / json-net.aspx )
- JsonEx( code.google.com/p/jsonexserializer )
- Fluent Json( fluentjson.codeplex.com 、 code.google.com/ p / fluent-json )
パフォーマンスを測定するために、2種類のテストが実行されました。
テスト番号1。 シリアライザーが10,000回初期化され、同じオブジェクトがシリアル化されました。
テスト番号2。 シリアライザーが作成および初期化された1回。 シリアル化は10,000回実行されました。 このテストは、オブジェクトのタイプに関する情報を事前に受け取った「スマート」シリアライザーがより高速に変換を実行することを期待して考案されました。 場合によっては、予備的な初期化が不可能であり、さらにそのようなテストの結果はダッシュでマークされます。
テスト環境:
サブジェクトには、プラットフォームの一部である2つのクラスがあります。つまり、Monoと.NETでの作業に違いがある可能性があります。 私はUbuntuをメインの唯一のOSとして使用しているため、.NETのテストにはVirtualBox仮想マシンを使用しました。 そして正確には:
- モノラル構成:Intel Atom 330、4Gb + Ubuntu 10.10、MonoDevelop 2.6、Mono 2.10.5
- .NET構成:VirtualBox、1.5GB、Windows XP、VS2010、.NET Framework 3.5
ストリング連結
まず、単純なToString()と連結による直列化のテスト結果を示します。 「本番」では、この方法はまれにしか正当化できません。 参照として使用するために検討します。 JSON形式の文字列をより高速に取得する方法を考えるのは困難です。
以下のテスト結果:
テスト番号1 | テスト番号2 | |
.NET | 0.25秒 | - |
モノ | 0.6秒 | - |
明らかな理由により、テスト2を実行することは不可能です。
JavaScriptSerializer
JavaScriptSerializerは、.NET / MonoプラットフォームのSystem.Web.Script.Serialization名前空間にあります。 コード例:
var serializer = new JavaScriptSerializer();// string jsonResult = serializer.Serialize(Program.bookA);//
JavaScriptConverter、RegisterConvertersクラスを使用して、さまざまなデータ型のシリアル化メソッドをオーバーライドする機能が宣言されています。 これは、たとえばDateTimeまたは列挙型の変換に役立ちます。 この機能を使用せずにテストを実施しました。
テスト結果:
テスト番号1 | テスト番号2 | |
.NET | 4秒 | 3.5秒 |
モノ | 5秒 | 5秒 |
DataContractJsonSerializer
すぐに使用できる別のシリアライザーは、System.Runtime.Serialization.Json名前空間にあります。 使用中は、文字列ではなくストリームでシリアル化が行われることを除いて、前のものと大差ありません。 例:
var serializer = new DataContractJsonSerializer(typeof(Book)); MemoryStream ms = new MemoryStream(); serializer.WriteObject(ms, Program.bookA); string jsonResult = Encoding.Default.GetString(ms.GetBuffer());
.NETとMonoでこのツールを使用する場合、違いがあります。 .NETでは、シリアル化可能なクラスとプロパティをそれぞれ[DataContract]属性と[DataMember]属性でマークする必要があります。 Monoでは、これらの属性はオプションです。
テスト結果は、違いは属性だけではないことを示しています。
テスト番号1 | テスト番号2 | |
.NET | 1.5秒 | 1.5秒 |
モノ | 34秒 | 34秒 |
今後は、1.5秒と言います。これはすべての被験者の中で最高の時間で、34秒は最悪です。
流FluなJSON
このシリアライザーの利点(および誰と欠点)は、プロパティを柔軟にマッピングできることです。 ビジネスロジックレイヤーに属性を入力する必要はありません。サードパーティのライブラリを使用する場合は問題があります。 ビジネスロジック層のデータ構造をクライアント/サーバー交換のデータ構造に変換するための中間クラスは必要ありません。 主張されている「チップ」のもう1つは、大きなデータセットのマルチスレッド処理の可能性であり、これにより高いパフォーマンスが得られます。 私の場合ではありません。
以下のサンプルコードは、この仕組みを示しています。
var serializer = Json.EnoderFor<Book>(config => config .MapType<Book>(map => map .AllFields() .Field<DateTime>(field => field.PubDate, pubDate => pubDate .EncodeAs<string>(value => value.ToShortDateString())) .Field<BookType>(field => field.Type, type => type .EncodeAs<int>(value => (int)value) .To("book_type"))) .MapType<Author>(map => map.AllFields()) .UseTidy(true) ); string jsonResult = serializer.Enode(Program.bookA);
上記の例のように、シリアル化可能なデータ型に列挙型またはDateTimeのプロパティが含まれている場合、それらの変換を指定する必要があります。 Fluent Jsonは、それ自体で何をすべきか疑問に思っています。
テスト結果:
テスト番号1 | テスト番号2 | |
.NET | 52.5秒 | 9秒 |
モノ | 34秒 | 10秒 |
JsonExSerializer
開発者の保証によると、このツールは、他のライブラリが提供しないオブジェクトの正確なシリアル化/逆シリアル化のために設計されています。 私にとってこれは最も重要なことではありません。スピードをテストします。 コード例:
var serializer = new Serializer(typeof(Book)); var memoryStream = new MemoryStream(); serializer.Serialize(Program.bookA, memoryStream); var jsonResult = Encoding.Default.GetString(memoryStream.GetBuffer());
JsonExのジューシーな機能は、フォームのフォーマットとコメントを結果に追加することです:
/* Created by JsonExSerializer Assembly: JsonTestConsole, Version=1.0.4347.32516, Culture=neutral, PublicKeyToken=null Type: JsonTestConsole.Book */
書式設定は、たとえば、設定をファイルに保存するときに役立ちます。この設定は、後でテキストエディターで編集できます。
テスト結果:
テスト番号1 | テスト番号2 | |
.NET | 32秒 | 8秒 |
モノ | 34秒 | 10秒 |
ニュートンJSON.NET
機能の説明には、「。NETの組み込みJSONシリアライザーよりも高速な高性能」という興味深い行があります。 ニュートンを使用したサンプルコードは1行に収まります。
string jsonResult = JsonConvert.SerializeObject(Program.bookA);
初期化は必要ありませんが、非常に良い時間を示しています。
テスト番号1 | テスト番号2 | |
.NET | 1.5秒 | - |
モノ | 2秒 | - |
おわりに
テスト結果は、両方の構成の時間(ミリ秒単位)の増加順にソートされています(列Kは、テストが「文字列連結」よりも遅い回数を示します)。
プラットフォーム | モノ | .Net Framework | ||||
シリアライザー | テスト番号1 | テスト番号2 | K | テスト番号1 | テスト番号2 | K |
ストリング連結 | 600 | - | 1 | 250 | - | 1 |
ニュートンJSON.NET | 2,000 | - | 3.4 | 1,500 | - | 6 |
JavaScriptSerializer | 5,000 | 4,000 | 8.3 / 6.7 | 1700 | 1700 | 6.8 |
JsonExSerializer | 34,000 | 10,000 | 56.7 / 16.7 | 4,000 | 3,500 | 16/14 |
流FluなJSON | 34,000 | 10,000 | 56.7 / 16.7 | 32,000 | 8,000 | 128/32 |
DataContractJsonSerializer | 34,000 | 34,000 | 56.7 / 56.7 | 1,500 | 1,500 | 6 |
この表は、Monoでアプリケーションを駆動する計画がある場合、またはプラットフォームが定義されていない場合、サードパーティライブラリNewton JSON.netを使用することをお勧めします。Win+ .NETとLinux + Monoの両方で良好な結果を示します。 ターゲットの.NETプラットフォームと属性バインディングが気にならない場合は、組み込みのDataContractJsonSerializerで十分です。 両方のオプションがあなたに合わないなら、あなたはあなた自身のライブラリを発明することができます-努力するべき多くがあります。
ここでテストコード: code.google.com/p/research-net-json/source/browse/Main.cs サードパーティのライブラリを個別にダウンロードする必要があります。もう一度リンクします:
- ニュートンJson.net:json.codeplex.com、james.newtonking.com/pages/json-net.aspx
- JsonEx: code.google.com/p/jsonexserializer
- Fluent Json: fluentjson.codeplex.com 、code.google.com/ p / fluent-json
UPD。 さらにいくつかのシリアライザーでテストを補足します( atd 、 skyboy 、 Guderian 、およびkekekeksに感謝します )。
プラットフォーム | モノ | .Net Framework | ||||
シリアライザー | テスト番号1 | テスト番号2 | K | テスト番号1 | テスト番号2 | K |
新しいStringBuilder(400) | 550 | - | 0.9 | 270 | - | 1 |
サービススタック | 1,300 | - | 2.2 | 1,200 | - | 4.8 |
Fast JSON | 2 600 | - | 4.3 | 1,200 | - | 4.8 |
ジェイロック | 8,200 | - | 13.7 | 9,200 | - | 36.8 |
ご覧のとおり、新しいリーダー-ServiceStackが登場しました。
PS間違いに気付いた場合、または他のライブラリを知っている場合は、書いてください。喜んで記事を補足します。