Msgpack cli-tech-aid-2013

2,572 views

Published on

0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,572
On SlideShare
0
From Embeds
0
Number of Embeds
104
Actions
Shares
0
Downloads
7
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Msgpack cli-tech-aid-2013

  1. 1. MessagePack CLI @yfakariya
  2. 2. SIer でスキマを埋める仕事をしてます プログラミング歴≒.NET歴 API 周りとかの仕事が得意です ご縁があり翻訳とかしてます • 『.NET のクラスライブラリ設計』 • 『プログラミング .NET Framework』(第3版~)
  3. 3. MessagePack CLI のご紹介 • MessagePack とは • MessagePack CLI とは • 0.4.0 について • 今後の予定 • Deep Dive
  4. 4. バイナリ形式の自己型記述型データフォー マット • 数値やフラグを小さなバイトで表現可能 • 文字列中心だとそれほど変わらない • 画像を BASE64 化したりする必要がない • ストリーム自体に型情報を付与
  5. 5. さまざまな言語で実装 • つまり、バイナリ形式で他の言語と通信できる • 言語(https://github.com/msgpack/より) • C++ • Ruby • Java • CLI(C#,VB,F#,etc…) • JavaScript(Node.js) • Python • Lua • Erlang • Haskell • D • Go • Perl • Smalltalk • OCaml • PHP
  6. 6. だいたい Protobuf と同じ コンパクト • -31~127 までの整数は型情報付きで1バイト • bool、nil は 1 バイト • 要素数 15 以下の配列、map、バイト数 31 以下の 文字列(UTF-8)ヘッダは型情報込みで 1 バイト • つまり、フラグとか整数にするととてもコンパク ト
  7. 7. 都道府県と郵便番号と住所のレコード • MSKK の住所だとこんな感じ • 0x93, 0x0C, 0x97, …, 0xD9, 0x27,… FixArray3 (構造体の フィールド数 が 3なので) PositiveFixNum5 1 (JIS都道府県 コードを数値化、 ここでは13) FixStr7 (郵便番号7ケ タ、文字列とし て) この後7バイトが UTF-8の郵便番号 Str8 + バイト数 (0x27) 住所本体のUTF-8 文字列
  8. 8. Common Language Infrastructure 用の実 装 • C# だけでなく、VB も OK  動くけど、F# や Iron* や PowerShell 向きではない • Mono でも動く • Silverlight/WP7.1 でも動く  自動テストがないのがネック 公式 Msgpack リポジトリの一員 • https://github.com/msgpack/msgpack-cli Apache 2 ライセンス
  9. 9. シンプルな API • 『Framework Design Guidelines』訳した人として も頑張りました。 かなりはやい • 0.4.0 Beta2 では、protobuf-net ±15% 程度 他の言語のバインディング豊富 • https://github.com/msgpack • それぞれの言語に合わせた API
  10. 10. 本家 issue 128 対応 • bin 型の対応:文字列でないバイナリ型をサポー ト • str8 型の対応:ディクショナリのキーなどで多用 される、32~127 バイトの文字列のサイズ削減 • ext 型の対応:AP 固有の型情報をバイナリそのも のに埋め込むフレームワーク  別の言語や実装で読み込んだ時に、そのデータが特定 の「拡張型」を意図していたことがわかるように。
  11. 11. Issue 128とは • MessagePack の仕様は、C++ や Ruby との互換 性を考慮して、文字列とバイト列を区別していな かったが、それだと JavaScript なんかで結構困 る、と言う話に標準化で商売している人が入って きたりしてえらいことになったスレッド(特徴: 長い)  https://github.com/msgpack/msgpack/issues/128
  12. 12. パフォーマンスチューニング • 苦節1年、ようやくパフォーマンスを向上できま した。 • 違ったもの  ストリームの読み取り(によるバイト配列生成)がボ トルネック説  仮想メソッド呼び出しオーバーヘッド説 • 原因  Nullable<T> のオーバーヘッド • Nullable<T> の API を deprecated にして解消。。。
  13. 13. そもそも論 • 最初からパフォーマンスを指向していない実装 で、ベンチマークとか出されて比較されると割と つらい • 先を見越せる経験、熟慮、運が大事 プロファイラをあてにしすぎない • ボトルネックがなく、なんか遅いときには役に立 たない(Nullable<T> のオーバーヘッドとか出て こない)
  14. 14. プラットフォーム強化 • Xamarin.Android • Xamarin.iOS • .NET Micro Framework  Issue #7 • WinRT(現在は CoreCLR 対応版のみ) • Windows Phone 8 まずは動作確認レポート募集中です!
  15. 15. NuGet から Msgpack cli をインストールし てみてください! フィードバックお待ちしてます! • 日本語でツイートが手軽です。  Github の issue に英語でやってくれた方が、議論は深 まると思いますが Happy Hacking!
  16. 16. Serialization API • MessagePackSerializer<T> • SerializationContext MessagePackObject T Primitive API • Packer • Unpacker <<corresponds>> <<uses>> <<corresponds>> System.IO.Stream <<uses>>
  17. 17. MessagePack 型システムの CLI 表現 • 整数 • 浮動小数点(IEEE 823 2進) • バイナリ(0.4 以降は文字列と純粋バイナリを区 別) • 配列 • マップ(ディクショナリ) • 拡張型(0.4 以降) • 真偽値 • nil
  18. 18. 軽量な値型 型変換演算子による CLI/FCL プリミティ ブへの変換 特殊な型: • 配列:IList<MessagePackObject> • ディクショナリ: IDictionary<MessagePackObject, MessagePackO bject>
  19. 19. 値のバイナリ表現を格納するためのビット 列 • 8bit(UInt64) • Single/Double は適宜変換して返す オブジェクトを格納するためのフィールド • 参照型(Byte[]、String、IList<MPO>、 IDictionary<MPO,MPO>) • または値型フィールドのセマンティクスを表現す る「型オブジェクト」 default(MPO) == MPO.Nil
  20. 20. MessagePack ストリームと MessagePackObject の相互変換 • XmlReader/Writer、StAX 相当の役割 • コレクションの Unpack のステート管理 • エンディアンの対処 • パフォーマンス上クリティカルなレイヤ • 通信遅延の待機や複数ストリームの Aggregate、 バッファリングなどの機能は持たない  Stream クラスの役割と割り切っている
  21. 21. 素直な実装 • エンディアンの切り替え • できる限りコンパクトな表現を選ぶ  値1Lは int64 でなく PositiveFixNum1 PackerCompatibilityOptions • MsgPack issue 128 以前の実装が読めるバイナリ を吐く  バイト列を Raw 型(文字列かもしれないバイナリ)で 出力  Str8 を使わない
  22. 22. SubtreeUnpacker • コレクションの入れ子のステート管理を担当 • XmlReader.ReadSubtree() と同じ考え方 • 処理は ItemUnpacker に委譲 ItemUnpacker • ストリームの読み取りと解釈
  23. 23. パフォーマンスネック • MessagePackObject への Unpack • 現在 Unpack 中の状態(型は何バイトか、要素数 はいくつか、キーなのか値なのか…)を保持 最適化 • 泥臭い  メソッド呼び出しオーバーヘッド削減のため、T4 によ る「マクロ展開」(あまり効果がない気がするので、 リファクタリングするかも)  FixNum や Boolean 値の MPO コンストラクタオー バーヘッド削減のためのルックアップ配列
  24. 24. シリアライザ • 任意のオブジェクトと MessagePack ストリーム の相互変換 • API は少数  MessagePackSerializer クラス:ファクトリ  MessagePackSerializer<T> クラス:シリアライザの定 義  SerializationContext クラス:シリアライザのリポジト リ  SerializerGenerator クラス:シリアライザを DLL とし て書き出す
  25. 25. シンプル指向 • 循環参照はサポートしない  サポートしても他の言語バインディングがサポートし ていない • したがって、ISerializationFormatter ではないし、 XmlObjectSerializer でもない • 限定されたカスタマイズポイント  IPackable/IUnpackable と SerializationContext
  26. 26. ISerializable 相当の低レベルインターフェ イス Packer/Unpacker を受け取り、自分のイン スタンスフィールドの状態を読み書きする Java 版との機能的互換性が主な目的
  27. 27. シリアライザの構成を表現 • 静的な Default  アプリケーション内のシングルトン • インスタンスとして引き回し可能 • DI コンテナフレンドリではないが、Composition Root で構成して、Default に突っ込んでおくのは 可能 • フレームワークなどを実装する場合、フレーム ワーク内で SerializationContext を保持してお き、設定の Isolation が可能
  28. 28. シリアライザのリポジトリを保持 • 型 T をキーにして、MPS<T> のインスタンスを保 持 • このリポジトリを直接変更することで、任意の MPS<T> 実装でシリアル化をカスタマイズ可能 • FCL の基本型のシリアライザが既定で登録済み (パフォーマンス向上のため)
  29. 29. MPS<T> を動的に生成 • AutoMessagePackSerializer<T>  動的生成 MPS<T> の基本構成  対象の型に依存しないジェネリック処理を実装 • 動的生成  T のフィールド/プロパティに読み書きに特化したコー ド生成  ボックス化の削減  JIT コンパイルによるパフォーマンス向上
  30. 30. Pack と Unpack で動作が異なる • Pack は SerializationContext の設定によって、オ ブジェクトをフィールド値の配列にするか、マッ プにするのかが異なる  既定では配列(他の言語に合わせている)  Map の方がデータ的に堅牢 • Unpack は配列でもMapでも来たものを受け入れ る
  31. 31. コレクションの Unpack • IEnumerable<T> 派生型の読み取り専用フィール ド/プロパティの場合、メンバー宣言型が Add(T) を宣言していれば、それを使用して Unpack 可能 • つまり、  public IList<string> Foo{get{…}} をサポートしている。
  32. 32. コード生成戦略 • 基本は Reflection.Emit  MPS<T> 実装型にフィールドを生成できるため  T 型の各フィールド/プロパティ用の MPS<Tn> を フィールドに保持 • Silverlight4 用の DynamicMethod モード  T 型の各フィールド/プロパティ用の MPS<Tn> は、実 行時に SerializationContext からルックアップ • WindowsPhone/WinRT 用の ExpressionTree モー ド  ルックアップ
  33. 33. カスタム属性なしでも「空気を読んで」対 応 [Serializable] がついている場合、 [NonSerialized] を尊重 [DataContract] がついている場合、 [DataMember] を尊重 • Id は 0 ベース • 互換性オプションで 1 ベースにもできる (protobuf-net との切り替えを容易に)
  34. 34. ストリームに Nil があった場合に対処方法 を、プロパティ/フィールドに付与するカ スタム属性で指定可能 • Null にする(非 Nullable の値型だとエラー) • フィールドの値をいじらない • 常に例外
  35. 35. 実験中 コード生成とコンパイルのコストを省略す るために、MPS<T> を事前にファイルに 出力する機能 • AssemblyBuilder.Save() するだけ

×