2011年1月アーカイブ

2011年1月19日
| コメント(0) | トラックバック(0) Data::EncoderでBenchmarkしてみた

ということで、まずは結果から。

Benchmark: timing 10000 iterations of Dumper, JSON, MsgPack, Storable, YAML...
    Dumper:  5 wallclock secs ( 4.02 usr +  0.00 sys =  4.02 CPU) @ 2485.09/s (n=10000)
      JSON:  1 wallclock secs ( 1.37 usr +  0.02 sys =  1.39 CPU) @ 7199.42/s (n=10000)
   MsgPack:  1 wallclock secs ( 0.72 usr +  0.00 sys =  0.72 CPU) @ 13927.58/s (n=10000)
  Storable:  2 wallclock secs ( 1.53 usr +  0.05 sys =  1.58 CPU) @ 6349.21/s (n=10000)
      YAML: 40 wallclock secs (40.19 usr +  0.06 sys = 40.25 CPU) @ 248.45/s (n=10000)
            Rate     YAML   Dumper Storable     JSON  MsgPack
YAML       248/s       --     -90%     -96%     -97%     -98%
Dumper    2485/s     900%       --     -61%     -65%     -82%
Storable  6349/s    2455%     155%       --     -12%     -54%
JSON      7199/s    2798%     190%      13%       --     -48%
MsgPack  13928/s    5506%     460%     119%      93%       --

色々と駆使して今更チャットを作ってみたわけですが、適当に追加していると、本当に追加されているのかよく分からない場合があります。
元々はこんな感じです。

    var add_log = function(text){
        $('#for_ajax').prepend("<p>" + text + "</p>");
    };

で、それを以下のようにやってみました。

    var add_log = function(text){
        $('#for_ajax').hide().prepend("<p>" + text + "</p>").fadeIn();
    };

fadeInだけだと、エフェクトがかからないので一旦hideしてやらないといけないようです。
ただ、これだと今までに書いてある記事もすべて消えてから、全体にfadeInがかかるのでいまいちな感じです。
新しく追加する部分だけにエフェクトが欲しいと思って調べてみたところ、ありました。

    var add_log = function(text){
        $("<p>" + text + "</p>").hide().prependTo('#for_ajax').fadeIn();
    };

すでにある要素に新しい記事を挿し込む、という順序ではなく、新しい記事をすでにある要素に挿し込む、という順序でやれば、新しい記事だけにエフェクトを掛けてやることが可能でした。
どちらを主体にするかでエフェクトの範囲を決めることができます。

リファレンスを見ていると、appendToとかprependToとかをどういう風に使うのか不思議だったのですが、ようやく使い方を発見した感じです。

これは、なかなか良いですね。

JSONを返すスクリプトの記事で、リストを作るときに以下のようにしていたのですが。

    my @json;
    for my $msg (@{$messages}) {
        push @json,
          { id  => $msg->id,
            msg => $msg->msg,
            ts  => $msg->ts,
          };
    }
    $self->render(json => [@json]);

レコードの情報は、get_columnsで取得できることがわかった。
それをふまえて書くと、上の処理に相当するコードは以下のようになります。

    my @json;
    for my $msg (@{$messages}) {
        push @json, $msg->get_columns;
    }
    $self->render(json => [@json]);

ここまで来たら、mapを使って書いてみたいですよね。

    my @json = map { $_->get_columns } @{$messages};
    $self->render(json => [@json]);

で、これだけだったら、直接書いても良さそうです。

    $self->render(json => [map { $_->get_columns } @{$messages}]);

ただ、本当なら、$messagesから直に変換出来れば便利ですけどね。

Mojoliciousが1.01になりましたね。

まあ、それとは関係ないですが、jQueryを使ってAJAXなチャットを作ってみたので晒してみようかと思います。
AJAX自体、やった事が無いので、もっと良いやり方があるとは思います。
値の受け渡しはJSONを使ったのですが、Mojolicious側の受け取り方法がよく分からなくて$self->req->jsonとか、Mojo::JSON->newとかやっていたのですが、結果的に普通に$self->paramで受け取れるのがわかって、凄いと思いました。

JavaScript側では、Perlからのtime値をどうやって渡すのかが、調べていてもよく分からなかったので、正解に行き着くのが大変でした。
ミリセカンドで渡す、というのは気づきませんでした。
常識すぎてあまり書かれないんでしょうか…。

Mojolicious::Liteの記事でORLiteが日本語には対応できていません、と書いていたところ、スクリプト側で対応させる方法を教えていただきました。
私はsqlite_unicodeを、createやpackageの最後で設定してみたりしていたのですが、どれもうまくいかず諦めていました。

そこで、以下のように package Model のところで connect メソッドを上書きすることで、日本語文字列のポスト・表示にも対応することができました。

この程度の追記で対応できるのであれば、なかなか使い出がありそうです。

基本的には前記事と同じです。
私の観測範囲ではData::ModelよりもDBIx::Skinnyの方がよく使われているような気がしますが、テーブルとschemaを両方作る必要があるのがちょっと微妙に感じます。
DBIx::Skinny::Schema::Loaderというschemaを自動的に設定してくれるモジュールもあるので、それを使えば問題ないわけですが。

ORLiteの記事を見て「いいな」と思ったのは、テーブルの定義をするだけで使えるところでした。
あと、テーブル毎にクラスを自動的に作ってくれるようで、それも面白い機能だと思います。
しかし、Skinnyなどで言うconnect_optionsが設定(簡単に言えばsqlite_unicodeを有効に)できないため、日本語には対応できていません。
ORLite.pmのソースコードを書き換えてやればうまく動くのは確認済みですが、パッチを書いたりテストを書いたりまでは面倒で…。

まあ、そんなわけで和製のORMの代表格であるDBIx::Skinnyも使っておこうかと、そんな感じです。

先日1.0にバージョンアップしたMojolicious(::Lite)を本格的に触ってみようとアレコレやってみた。
MojoliciousのWikiにORLiteを使ったサンプルがあったのですが、残念ながらそのままでは日本語には対応していないので、他のORMを使ってみようという、そんな感じです。

Google検索

Last.fm

このアーカイブについて

このページには、2011年1月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2010年11月です。

次のアーカイブは2011年2月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Creative Commons License
このブログのライセンスは クリエイティブ・コモンズライセンス.
Powered by Movable Type