Php Meets Messagepack

22
PHP meets MessagePack, KLab株式会社 研究開発部 竹井英行 2009年11月13日 and I meets PHP Extension.

description

phpのエクステンションを作ろう

Transcript of Php Meets Messagepack

Page 1: Php Meets Messagepack

PHP meets MessagePack,

KLab株式会社 研究開発部 竹井英行

2009年11月13日

and I meets PHP Extension.

Page 2: Php Meets Messagepack

自己紹介•今年4月入社の新卒、竹井です

• 主にモバイル向けSNSやCMSの開発してます

• プライベートではUSBガジェットやロボット、プロダクトなどのハードウェアを開発してます

Page 3: Php Meets Messagepack

AGENDA

• MessagePackの紹介

• 仕様

• 特徴

• PHP Extensionを作ろう

• 概要

• PHP<‒>Cでの値の受け渡し方

Page 4: Php Meets Messagepack

MessagePackとは•古橋貞之(id:viver)さん考案

• 性能を重視したバイナリベースで高速な シリアライズ形式

• JSON : テキストベースのシリアライズ形式

• MessagePack = 速いJSON

• http://msgpack.sourceforge.jp

Page 5: Php Meets Messagepack

MessagePackとKLabの関係

• Kラボの稲田がPythonライブラリを開発

• でMessagePackを使用

• Erlang版も開発中

• PHP版はまだない!→ここは私が!!

Page 6: Php Meets Messagepack

MessagePackの仕様

•整数, Boolean, 文字列, 配列, 連想配列, nilをバイト列にシリアライズ

• データ型, データ(整数やfloat, double)

• データ型, 長さ, データ, データ,… (Raw, Array, Map)

• ビッグエンディアン

Page 7: Php Meets Messagepack

MessagePackとJSON

• [1,2,3]という配列のシリアライズ後の表現を比較

• json: [1,2,3]←テキスト

• 5B 31 2C 32 2C 33 5D (LEN:7)• msgpack: 93 01 02 03 (LEN:4)

Page 8: Php Meets Messagepack

一例• Positive FixNum(0~127) : 1byte

• uint 8 : 2bytes

0XXX XXXX

1100 1101 XXXX XXXX

• fix raw : (N+1)bytes [000XXXXX(=N)<32]

… N bytes101X XXXX

Page 9: Php Meets Messagepack

MessagePackの特徴

•シリアライズ/デシリアライズが高速

• シリアライズされたデータサイズが小さい

• フォーマット定義(IDL)が不要

• ストリーム処理ができる

Page 10: Php Meets Messagepack

シリアライズ/デシリアライズが高速

• [0, 1, 2, 3, ..., 2^24]という整数の配列

対象 形式 シリアライズ デシリアライズ

整数の配列msgpack 0.701秒 0.484秒json 8.11秒 5.83秒

文字列の配列msgpack 0.829秒 0.00581秒json 7.18秒 8.87秒

• ["", "a", "aa", ..., "a"*2^15]という文字列の配列

• MessagePackとJSONのベンチマーク*を比較

*:参考文献 http://d.hatena.ne.jp/viver/20080816/p1

Page 11: Php Meets Messagepack

シリアライズされた

•MessagePackはJSONと比べて60%程度の小ささ

• 32bitsの整数を保存する場合

• json : 最大10bytes (2^32で10桁)

• msgpack : 最大5bytes (データ型1+データ4)

対象 形式 サイズ

整数の配列msgpack 79.9MBjson 133MB

データサイズが小さい

Page 12: Php Meets Messagepack

フォーマット定義(IDL)が不要

• Protocol Buffers : Googleが開発した     バイナリエンコード手法

• IDL : フォーマットを記述するための言語

• Protocol Buffers はIDLで静的に型付け

• MessagePackは動的型付け(自己記述性)

• 必要になったときに静的型に変換する

参考文献 http://d.hatena.ne.jp/viver/20081116/p1

Page 13: Php Meets Messagepack

ストリーム処理ができる•流れてくるデータを順次ストリーム処理

することができる

• データ型, (長さ,)データで保存される

• メッセージとメッセージの切れ目を 知ることができる

• デシリアライザにデータを投げていく だけでメッセージを1つずつ取り出せる

Page 14: Php Meets Messagepack

アプローチ

• PEAR のように PHP でクラスライブラリ

を作る(ペアる)

• PECL のように PHP 自体を拡張する   モジュールを書く(ピクる)

PHPで汎用的なライブラリを作成する方法は2つ

Page 15: Php Meets Messagepack

なぜ ピクるのか?•過去に C で書かれた既存のライブラリを

流用できる

• MessagePackにはすでにCのライブラリがある!!

• PEAR のように PHP で書いたコードと 比べると高速に動作する

Page 16: Php Meets Messagepack

とても簡単だったPHP Extensionの作り方

• phpのソースをダウンロード・展開する

• extディレクトリに移動

• スケルトンを作成する (./ext_skel --extname=xx)

• $phpize

• Cのコードを書く←がんばりどころ!

• $./configure そして $make

• modules/*.soのできあがり congratulation!!

Page 17: Php Meets Messagepack

いろいろありますがつまり!

• phpからCの関数が呼べます!• 詳しくは「DSAS開発者の部屋:PHP Extension を作ろう」シリーズ参照        

http://dsas.blog.klab.org/archives/50777398.html 

• 値を渡す/返すを試みよう。……ん?

• PHP : 動的型付け,C : 静的型付け

• PHPのデータ表現(zend.h)を見れば一目瞭然!

Page 18: Php Meets Messagepack

typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object obj;} zvalue_value;

struct _zval_struct { zvalue_value value; /* value */ zend_uchar type; /* active type */ zend_uchar is_ref; zend_ushort refcount;};

php-x.x.x/Zend/zend.h より…

Page 19: Php Meets Messagepack

といっても

•値の受け渡しするための便利なマクロがたくさん用意されています

Page 20: Php Meets Messagepack

値を受け取る方法• ZEND_NUM_ARGS … 引数の数を取得する

• TSRMLS_CC … スレッドセーフなことを保証PHP_FUNCTION(example2){ char *str; int str_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) { return; } printf("%s\n", str);}

Page 21: Php Meets Messagepack

返値を返す方法• zval型のreturn_valueに値をセットする

• 最初に引数で渡された zval の参照で値を返している

#define ZVAL_LONG(z, l) {               \          Z_TYPE_P(z) = IS_LONG;        \          Z_LVAL_P(z) = l;              \}

#define RETURN_LONG(l) { RETVAL_LONG(l); return; }

#define RETVAL_LONG(l) ZVAL_LONG(return_value, l)

Page 22: Php Meets Messagepack

PHP Extension作りの参考資料

• php-x.x.x/ext ディレクトリにPECLのPHPエクステがたくさんあります

• msgpackのPHPエクステもJSONのものをリスペクトした形になっています

• Cでの配列と連想配列の判定など

• 近日中にmsgpack本家登録&PECL登録予定!乞うご期待!