Symfoware

Symfowareについての考察blog

FreeBSD + mono + C#でJSONエンコード、デコード

FreeBSD 10.1にmonoをインストールして色々試してみています。

オプジェクトをJSON形式のデータに変換するライブラリを調べていると、
こんな記事を見つけました。
.NETのJSONシリアライザの速度比較

Microsoftの.NETだと標準ライブラリは速度が出ない模様。
monoなら変化があるかな?と思ったので、適当にプログラムを書いて試してみました。

シリアライズ、デシリアライズを各々10,000回実行して速度を見てみます。


標準ライブラリ(DataContractJsonSerializer)



System.Runtime.Serialization.Json.DataContractJsonSerializerを使ったサンプルです。


  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Runtime.Serialization.Json;
  5. public class Sample {
  6.     
  7.     [STAThread]
  8.     public static void Main(string[] args) {
  9.         
  10.         Person p = new Person();
  11.         p.Id = 1;
  12.         p.Name = "Taro";
  13.         p.BloodType = BloodType.A;
  14.         p.BirthDate = new DateTime(2000, 1, 1);
  15.         p.FirendIds = new int[]{2, 3, 4};
  16.         
  17.         string json = write(p);
  18.         
  19.         var startDate = DateTime.Now;
  20.         
  21.         //write(p);
  22.         read(json);
  23.         
  24.         var endDate = DateTime.Now;
  25.         TimeSpan diff = endDate - startDate;
  26.         Console.WriteLine(string.Format("{0} ms", diff.Duration().Milliseconds));
  27.     }
  28.     
  29.     private static string write(Person p) {
  30.         
  31.         var serializer = new DataContractJsonSerializer(typeof(Person));
  32.         string json = null;
  33.         
  34.         for(int i = 0; i < 10000; i++){
  35.             MemoryStream stream = new MemoryStream();
  36.             serializer.WriteObject(stream, p);
  37.             
  38.             stream.Position = 0;
  39.             StreamReader sr = new StreamReader(stream);
  40.             json = sr.ReadToEnd();
  41.         }
  42.         
  43.         return json;
  44.     }
  45.     
  46.     private static void read(string value) {
  47.         var serializer = new DataContractJsonSerializer(typeof(Person));
  48.         
  49.         for(int i = 0; i < 10000; i++){
  50.             MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(value));
  51.             Person p = (Person)serializer.ReadObject(stream);
  52.         }
  53.     }
  54.     
  55.     
  56. }
  57. public enum BloodType
  58. {
  59.     A = 1,
  60.     B = 2,
  61.     AB = 3,
  62.     O = 4
  63. }
  64. public class Person
  65. {
  66.     public int Id { get; set; }
  67.     public string Name { get; set; }
  68.     public BloodType BloodType { get; set; }
  69.     public DateTime BirthDate { get; set; }
  70.     public int[] FirendIds { get; set; }
  71. }




コンパイルは-rでSystem.Runtime.Serialization.dllを指定する必要あり。


# mcs sample.cs -r:System.Runtime.Serialization.dll




変換後のjsonな文字列はこんな感じになりました。


{"BirthDate":"\/Date(946684800000)\/","BloodType":1,"FirendIds":[2,3,4],"Id":1,"Name":"Taro"}








Newtonsoft.Json



http://www.newtonsoft.com/json
Newtonsoft.Jsonを使用したパターンは以下のとおり。


  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using Newtonsoft.Json;
  5. public class Sample {
  6.     
  7.     [STAThread]
  8.     public static void Main(string[] args) {
  9.         
  10.         Person p = new Person();
  11.         p.Id = 1;
  12.         p.Name = "Taro";
  13.         p.BloodType = BloodType.A;
  14.         p.BirthDate = new DateTime(2000, 1, 1);
  15.         p.FirendIds = new int[]{2, 3, 4};
  16.         
  17.         string json = write(p);
  18.         
  19.         var startDate = DateTime.Now;
  20.         
  21.         //write(p);
  22.         read(json);
  23.         
  24.         var endDate = DateTime.Now;
  25.         TimeSpan diff = endDate - startDate;
  26.         Console.WriteLine(string.Format("{0} ms", diff.Duration().Milliseconds));
  27.     }
  28.     
  29.     private static string write(Person p) {
  30.         
  31.         string json = null;
  32.         
  33.         for(int i = 0; i < 10000; i++){
  34.             json = JsonConvert.SerializeObject(p);
  35.         }
  36.         
  37.         return json;
  38.     }
  39.     
  40.     private static void read(string value) {
  41.         
  42.         for(int i = 0; i < 10000; i++){
  43.             
  44.             Person p = JsonConvert.DeserializeObject<Person>(value);
  45.         }
  46.     }
  47.     
  48.     
  49. }
  50. public enum BloodType
  51. {
  52.     A = 1,
  53.     B = 2,
  54.     AB = 3,
  55.     O = 4
  56. }
  57. public class Person
  58. {
  59.     public int Id { get; set; }
  60.     public string Name { get; set; }
  61.     public BloodType BloodType { get; set; }
  62.     public DateTime BirthDate { get; set; }
  63.     public int[] FirendIds { get; set; }
  64. }




コンパイル時、Newtonsoft.Json.dllを指定します。
net45のdllを使用しました。


# mcs sample.cs -r:Newtonsoft.Json.dll




変換後のjsonな文字列はこんな感じになりました。


{"Id":1,"Name":"Taro","BloodType":1,"BirthDate":"2000-01-01T00:00:00","FirendIds":[2,3,4]}







結果



monoでもNewtonsoft.Jsonの方が速かったです。

シリアライズ

回数デフォルトNewtonsoft.Json
1374 ms190 ms
2388 ms189 ms
3376 ms188 ms
4429 ms188 ms
5381 ms185 ms
平均389.6 ms188 ms



デシリアライズ

回数デフォルトNewtonsoft.Json
1640 ms92 ms
2625 ms92 ms
3622 ms92 ms
4653 ms93 ms
5633 ms93 ms
平均634.6 ms92.4 ms

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2015/07/13(月) 23:55:32|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Mono xbuild(MSBuild)でプログラムのコンパイルを実行する | ホーム | FreeBSD + monoでC#のWebフレームワーク「Nancy」を動作させる>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1752-4f13a1bc
この記事にトラックバックする(FC2ブログユーザー)