PHP Memcached Extension をより軽量高速にしてみるテスト

php-memcached-dev/php-memcachedをforkしたmsgpack-and-snappyブランチで、シリアライズ方式にMessagePackを、圧縮方式にSnappyを選べるようにした。→GitHub

MessagePackを使うにはPECL msgpackをインストールした上で、configureのオプションに --enable-memcached-msgpack を、Snappyを使うにはSnappyをインストールした上で --with-snappy-dir を付ければよい。

MacPortsでライブラリを入れている場合の例:

phpize
./configure \
    --enable-memcached \
    --enable-memcached-msgpack \
    --with-libmemcached-dir=/opt/local \
    --with-snappy-dir=/opt/local \
    --with-zlib-dir=/opt/local
make
make install

今のところMessagePackシリアライザはデフォルトで有効に、Snappyコンプレッサは Memcached::setOption(Memcached::OPT_COMPRESSION_TYPE, Memcached::COMPRESSION_SNAPPY) で有効にする仕様。

もうちょい寝かしたら本家にpull requestを送る。

MessagePack+Snappyと、その他の組み合わせでベンチマークを取ってくださるお方を募集しております。

うにとじゅん菜のジュレ

石ガレイのマリネ 夏野菜と共に

冷製かぼちゃのスープ

塩釜を除いた鮑

うかい亭スペシャリテ 鮑の岩塩蒸し 2種のソースで

サーロイン

うかい牛サーロインステーキ

ガーリックライス

季節のデザート

<p>八王子うかい亭 ウェディングメニュー</p>

PHP 5.4.1の新機能: Scalaライクなミックスイン

2012年4月1日にリリースされたPHP 5.4.1では、マイナーバージョンアップにも関わらず言語仕様が拡張されるという、PHPクォリティ全開の変更があったので紹介しよう。


実体化時ミックスイン (Mix-in instantiation)

クラスをインスタンス化する際にuse文でトレイトを追加できるようになった。トレイトは実行時に解決されるので、クラス宣言より後にトレイトを宣言することも可能。

例1

<?php
class JoJo {}

trait HermitPurple {
    public function sayStand() {
        echo '隠者の紫';
    }
}

trait StarPlatinum {
    public function sayStand() {
        echo '星の白金';
    }
}

$joseph = new JoJo use HermitPurple;
$jotaro = new JoJo use StarPlatinum;

$joseph->sayStand();
echo '/';
$jotaro->sayStand();

出力1

隠者の紫/星の白金

当然オートボクシングもできる。

例2

<?php
trait Hello {
    public function sayHello() {
        echo 'Hello';
    }
}

(new stdClass use Hello)->sayHello();

出力2

Hello

衝突の解決

new-use構文によるミックスインでもinsteadof演算子やas演算子によって衝突の解決や別名の定義が可能。

例3

<?php
trait A {
    public function smallTalk() {
        echo 'a';
    }
    public function bigTalk() {
        echo 'A';
    }
}

trait B {
    public function smallTalk() {
        echo 'b';
    }
    public function bigTalk() {
        echo 'B';
    }
}

$talker = new stdClass use A, B {
    B::smallTalk insteadof A;
    A::bigTalk insteadof B;
    B::bigTalk as talk;
};
$talker->smallTalk();
echo ',';
$talker->bigTalk();
echo ',';
$talker->talk();

出力3

b,A,B

無名トレイト (Anonymous Traits)

実体化時ミックスインでは、use文のブレース中にメソッドおよびプロパティを記述できる。厳密にはトレイトでないのだが、便宜上この機能を無名トレイト (Anonymous Traits)と呼ぶ。

例4

<?php
(new stdClass use {
    public function sayHello() {
        echo 'Hello';
    }
})->sayHello();

出力4

Hello

名前付きトレイトとの併用

無名トレイトは通常の名前付きトレイトと併用することもできる。

例5

<?php
class JoJo {}

trait GoldExperience {
    public function sayStand() {
        echo 'ゴールド・エクスペリエンス';
    }
}

trait Requiem {
    public function sayStand() {
        echo 'レクイエム';
    }
}

$giorno = new JoJo use GoldExperience, Requiem {
    GoldExperience::sayStand as sayStand1;
    Requiem::sayStand as sayStand2;

    public function sayStand() {
        $this->sayStand1();
        echo '・';
        $this->sayStand2();
    }
};

$giorno->sayStand();

出力5

ゴールド・エクスペリエンス・レクイエム

implements演算子による機能チェック

PHPのトレイトは型システムとしての機能を備えていないので、instanceof演算子でトレイトが追加されているか調べることはできない。しかしミックスインによってインスタンス毎にトレイトを追加できるので、instanceof演算子だけではインスタンスが持つ機能を判定できなくなった。そこで、implements演算子を用いてトレイトの機能をチェックする。

例6

<?php
class Dio {}

trait TheWorld {
    public function sayHello() {
        echo 'WRYYY!';
    }
}

$dio = new Dio use TheWorld;
var_dump($dio implements TheWorld);
$dio->sayHello();

出力6

bool(true)
WRYYY!

注意事項

implements演算子による機能チェックは Class implements Interface によるクラス宣言時と同等のシグネチャ検証をする。そのため、右辺のトレイトが提供する機能を備えていれば、そのトレイトが追加されていなくても真となる。

例7

<?php
class Dio {}

trait TheWorld {
    public function sayHello() {
        echo 'WRYYY!';
    }
}

trait ScaryMonsters {
    public function sayWorld() {
        echo 'WRYYYYYY!';
    }
}

$dio = new Dio use TheWorld { TheWorld::sayHello as sayWorld };
var_dump($dio implements TheWorld);
var_dump($dio implements ScaryMonsters);
$dio->sayWorld();

出力7

bool(false)
bool(true)
WRYYY!

php-mecab 0.5.0

拙作php-mecabMeCab 0.99でビルドできなかったり、PHP 5.4でビルドできなかったのを修正した。

MeCab 0.99に対応するため、構造体の変更によって互換性が失われた関数を無効にしている。今後の開発はPHP 5.3.0以降とMeCab 0.99以降のみサポートし、MeCabの新たな機能を網羅したい。

GitHub/rsky/php-mecab

ダウンロード

他のプロジェクトたちも、とりあえずセーフモードチェックを切る対応をしないと・・・


追記

OpenDogs PHP extension channelも更新した。

インストール:

pear channel-discover pecl.opendogs.org
pear install opendogs/mecab

アップグレード:

pear upgrade opendogs/mecab

MacでAndroid端末のUSBデバッグをする方法

SDKのインストールとか端末側でUSBデバッグを有効にする方法は割愛。

システムプロファイラでデバッグしたい端末の製造元IDを調べて、~/.android/adb_usb.ini に追加する。以上。

ソニー製端末の製造元IDは 0x054c だが、0x54c とxに続く0は削ってもOK。ただしCを大文字にするとアウト。マスト小文字。なんでやねん。

0x054cadb installしたとき

1315 KB/s (3183951 bytes in 2.363s)
        pkg: /data/local/tmp/Hoge-debug.apk
Success

0x054Cadb installしたとき

error: device not found

PHP 5.4におけるZend APIの変更点

16日目@yohgakiさんに続いて、2回目のPHP5.4 Advent Calendar 2011 エントリです。

今回はヘッダファイルの差分を見てPHP 5.3からPHP 5.4のZend APIにどのような変更があったのかを見てみましょう。バイトコードに対する処理が書かれているzend_vm_def.hとzend_vm_execute.hを除いた全差分はGistに貼り付けました

全体的には char * / void * と定義されていた引数が const char * / const void * になっている箇所が多く見られます。この変更はPHP 5.2から5.3にもありましたが、中身を書き換えないポインタはconst修飾するというセオリーがより徹底されており、地味ながら良い変更ですね。


トレイト関連のAPI追加 (zend.h, zend_API.h)

トレイトが導入されたことにより、トレイト関連のAPIが追加されているほか、zend_class構造体もトレイトをサポートするために大きな変更があります。 (詳細はあとで書く)


zvalを操作するマクロの追加 (zend.h)

マクロ ZVAL_COPY_VALUE(zval *z, zval *v)INIT_PZVAL_COPY(zval *z, zval *v) が追加されています。

前者はzvalの「値」を同じにするために、後者はzvalの参照カウントを1にし、他のzvalへの参照であるというフラグを0にします。

このような処理はPHP 5.3までは個別に書かれていたのですが、定型処理をマクロ化したことでZend Engine/PHP本体だけでなく変数を操作する拡張モジュールが書きやすくなるかもしれません。少なくとも「定型処理に名前を付ける」ことで意図が明確になり、読みやすさは格段に向上します。


カレンダーの締め切りの時間が迫ってきたので、いったんここまでで投稿します。朝までに追記しますので請うご期待。

明日はついにここいち兄さん登場です!