2008年1月アーカイブ

隣のO澤くんが「Perlにデフォルトで入ってるモジュールが何かあるのかわかんないんですよねぇ」とか言ってるから、ワンライナー:

# もしModule::CoreListがインストールされてないなら cpan install Module::CoreList perl -MModule::CoreList -e 'print "$_\n" for sort keys %{$Module::CoreList::version{5.008008}} '


これで一発で出るよ!
AnyDBM_File Attribute::Handlers AutoLoader AutoSplit B B::Asmdata B::Assembler B::Bblock B::Bytecode B::C B::CC B::Concise B::Debug B::Deparse B::Disassembler B::Lint B::Showlex B::Stackobj B::Stash B::Terse B::Xref Benchmark ByteLoader CGI CGI::Apache CGI::Carp ...

Cache::Memcached::libmemcachedをリリースしました

アナウンスし忘れてたけど、Cache::Memcached::libmemcachedをリリースしたよ。主な違い:
  • 名前が変わった!w LibMemcached -> libmemcached
  • Memcached::libmemcachedをバックエンドとして使用している
    • libmemcached本体が梱包されている!
あとは細かいところがちらほらと。しかしMemcached::libmemcachedのXSコードすげぇよ、本当。

DBIx::Replicateのリファクタリング

誰か OO な設計にリファクターして、いろんなコピー戦略を実装できるようにしてくれないかなぁ。
データベースをコピーするモジュール DBIx::Replicate - Kazuho@Cybozu Labs
早速したよ!

MOONLIGHT MILE

ここ最近で一番のおススメの漫画は「MOONLIGHT MILE」。最後のフロンティアたる宇宙(作品中では今は月世界)を開拓する人達、それにまつわる国と国の駆け引き、家族、夢を描いている。

たま〜〜〜〜〜に立ち読みするスペリールで連載中の話を読んだりはしていたのだが、なにせ話が意外とスローテンポで進むため、連載中の作品を読んでもイマイチ意味がわからなかった。けど昨年末からブックオフでちょぼちょぼ買い始めたら、これがおもしろくて止まらない。最初の三冊くらいは青年漫画にアリガチな過剰なエロのオンパレードなんだが、物語が進むに連れいい感じに話がふくらんでいく。

ネットで見る限り、技術的な正確さを欠く表現等も見受けられるらしいが、そんな事も気にならないと思う。是非コミックス一気読みをおススメする。

ちなみにはまってからはブックオフに出回るのが待ちきれずに全部新品でコミックスは揃えた。
「もやしもん」の後がまにやってる「墓場の鬼太郎」、なかなか味があるというか、シュールなアニメなんだが、この内容はともかく、電気グルーヴが歌っているOP曲がなんかイイ! 聞いてると体が動く感じ。

携帯変更

携帯を変えました。長らく愛用していたシャープ製品ですが、値段とか、あの回るディスプレイが気に入らないとか、諸々の理由を踏まえて有機ELディスプレイのW53Hにしました。

使用しはじめて今日で3日目。今のところ懸念事項であった漢字変換が案の定気に入らないということ以外は結構いけてます。ワンセグは感動はしたけど、やっぱみねぇな、こりゃ。たまにバスに乗る時にでもみさせていただきましょう。

とっても薄いのはひじょうに魅力的。
ついにMemcached::libmemcachedのレポジトリへのコミット権もらっちった。で、いきなりTim君がcallbackの仕様の云々をかるーく説明してかるーく「こんな感じでリファクタリングするといいお☆」とか言ってくるもんだからコードを読んでみたらわぁかんねぇええええええ!w

このXSはむずいなあ。でもやっぱり本当にCで書くんならこういう事できないと駄目だよな。

つか、俺のオリジナルのパッチを文句も言わずにこんなにリファクタリングしたtim++;

perl-memcached branch

Time Bunceからのメールで、最新libmemcached (0.14)で任意のデータをmemcached_st に紐付けられるようになったのでMemcached::libmemcachedも0.1401にバージョンアップしたとの報告が!そこで早速Cache::Memcached::LibMemcachedのバックエンドとしてMemcached::libmemcached を使うブランチを作成したよ。

Green Green

小学校で使ってた歌の本にも載ってた「グリーングリーン」。最近トヨタのCMに使われてるけど、これが元の英語の歌詞で歌われていてどんな歌詞だったか知らなかったので調べてみた:http://www.traditionalmusic.co.uk/folk-song-lyrics/Green_Green_Its_Green_They_Say.htm

こ、これ・・・ヒッピーというか、放浪人の歌じゃねぇか!ある日パパとこの世に生きる喜びと悲しみについて語り合ったんじゃないのか!(笑) 「この世のどんな女も俺を一カ所に留める事なんてできないのさ」だって!

いやあ、しらんかったなぁ

Tim Bunceとコラボできるって素晴らしいね。

Time Bunceと言えばPerlで誰でも使った事のあるDBI.pmの作者/メンテナーでありますが、彼はMemcached::libmemcachedも書いています。この間俺もCache::Memcachedの互換インターフェースとしてCache::Memcached::LibMemcachedを書いたわけですが、このおかげでTime Bunce氏と少々交流が生まれました。

そしたら今朝程メールが来て、libmemcachedのドキュメントの不具合もあり、自分が書いたコードにメモリーリークが生まれたのを発見した、とTimからlibmemcachedの作者へのメールが送られていて、それに自分もCCされていた。で、文中には「ちなみにCache::Memcached::LibMemcachedも同じリークしてるよ」って!おお、知らんかった。ありがとおお!

ってことで直した。codereposのrev 5242で直ってます。

前にid:tokuhiromも同じような事を言っていたけど、オープンソースの世界ってこういうところがやめられない要因のひとつだよね。なんか知らない間に誰かが書いたコードが有機的に自分の書いたコードに影響を与えてまたそれがフィードバックされていく・・・すばらしいな。

これから先もどんな仕事をしていてもオープンソースの世界には関わって行きたいと思う。

サーバー追加

サーバーを某案件用に追加。好きにできるサーバーがさらに増えたわけだが、これが半年前にあったら日記才人続けてたかなぁ?とか一瞬思ってしまった。いや、多分やってないけど。

しかしportupdateは時間かかった。

Re: 結局どっち使えばええのん?

Memcachedクライアント戦国時代に突入した感のある昨今でございますが、こちらのエントリを見るとget_multi()の性能はC::M::Fastのほうが数パーセント速いということらしい。で、del.icio.usのコメント欄にも書いてあった「結局どっち使えばいいのか?」という事に関してなんだが。

色々自分でベンチをやってみた限り、単体のget()の場合LibMemcachedのほうが50%ほど速い。get_multiのほうは最低2%、最高で10%くらいFastのほうが速い。だから単体get()を多用する場合はLibMemcached、get_multi()を多用する場合はFastでいいんじゃね?

libmemcachedのほうはきっとCの頭いい人がもっと速くしてくれるよ!と流してみる。

[良スレ] PerlプログラマーのためのC?

P5Pで今日盛り上がっているスレッド

http://www.gossamer-threads.com/lists/perl/porters/225077?do=post_view_threaded

いいね。今のところ「これだ!」という答えはないけれども、word-boundary云々とか、なかなか有益な情報があった。もっと続くと嬉しい。

ケータイ大喜利のMEGUMI

NHKでケータイ大喜利を見ていたらMEGUMIが出ていたのだが、なんか顔かわったな?痩せた?

しかしこの番組、よくNHKでやってられるなー。

LibMemcached 0.00006

インストールプロセスとreplace()を直した0.00006をアップしたよ。
先輩! 仕事で疲れた脳を休めようと、先ほどlibmemcachedが備えているno_blockをCache::Memcached::LibMemcachedからも設定できるようにしてみたんです。で、ベンチマークを取ってみたところ・・・
daisuke@beefcake Cache-Memcached-LibMemcached$ perl -Mblib tools/benchmark.pl ==== Benchmark "Simple set() (scalar)" ==== (warning: too few iterations for a reliable count) Rate perl_memcahed memcached_fast libmemcached libmemcached_no_block perl_memcahed 7396/s -- -60% -77% -99% memcached_fast 18382/s 149% -- -42% -98% libmemcached 31646/s 328% 72% -- -97% libmemcached_no_block 1000000/s 13420% 5340% 3060%
なんですかこれ!速すぎて計測できない言われてる! やばいよ!
もちろん非同期モードで書き込み始めると戻り値を確認しないで書き続けるので速いのは当たり前っちゃあ当たり前なんだが、それにしてもこんな差がでるとは。

ちゃんとした値を取りたいのでset()を呼ぶ数を10倍にしてみました。結果:
daisuke@beefcake Cache-Memcached-LibMemcached$ perl -Mblib tools/benchmark.pl ==== Benchmark "Simple set() (scalar)" ==== Rate perl_memcahed memcached_fast libmemcached libmemcached_no_block perl_memcahed 6961/s -- -62% -78% -99% memcached_fast 18437/s 165% -- -42% -98% libmemcached 31827/s 357% 73% -- -97% libmemcached_no_block 1086957/s 15515% 5796% 3315% --
すげぇえええええええ!

自分的にはまった?部分はどうもmemcached 1.2.4でないとサーバー側が停止してしまったこと。これは俺の環境の問題なのか、サーバーの問題なのかは不明。

この機能は次のバージョン0.00005でリリースします。

POE::Component::Q4M

POE::Component::Q4M書いた(svn)これでPOEから非同期アクセス。APIがまだイマイチなので意見求ム
追記:get()だけじゃなくてset()もベンチとってみた。Cache::Memcachedと比べてget()はざっくり6倍から9倍、set()は2倍から4倍速いみたい。

追記2:一番最後のset()ベンチだけは::Fastが速かった事に今更気づいた。レポート読み間違え。なんとなーーーく俺のベンチでは圧縮が行われてない気がする。誰か知ってたら教えてください。

id:miyagawaさんがLibMemcached.pmに関して「cache::memcached::fast とか ::XS とかとのベンチはどれくらい?」と言っていたので、やってみた。

ベンチ対象はCache::Memcached, Cache::Memcached::Fast,それにCache::Memcached::LibMemcached。Cache::Memcached::XSはlibmemcacheをインストールしてもコンパイルできなかったのでパス。

ベンチの内容も、ただ単純にスカラーをget()するためのベンチマークだけではなく、スカラー、ハッシュ(つまりStorableでシリアライズする)、それに大きめのデータ(Compress::ZlibでmemGzipする)3つのパターンを組み込んでみた。

結果、圧倒的にlibmemcachedが速い。Perlバインディング自体ももう少し最適かできるかもしれないけど、今の感じだとPerlレイヤーで最適化できるところはほとんどないような気がするな。
daisuke@beefcake Cache-Memcached-LibMemcached$ perl -Mblib tools/benchmark.pl ==== Benchmark "Simple get() (scalar)" ==== Rate perl_memcahed memcached_fast libmemcached perl_memcahed 3837/s -- -80% -88% memcached_fast 18939/s 394% -- -42% libmemcached 32895/s 757% 74% -- ==== Benchmark "Simple get() (w/serialize)" ==== Rate perl_memcahed memcached_fast libmemcached perl_memcahed 3658/s -- -77% -84% memcached_fast 16077/s 340% -- -29% libmemcached 22727/s 521% 41% -- ==== Benchmark "Simple get() (w/compression)" ==== Rate perl_memcahed memcached_fast libmemcached perl_memcahed 3720/s -- -74% -81% memcached_fast 14535/s 291% -- -27% libmemcached 19841/s 433% 37% -- ==== Benchmark "Simple set() (scalar)" ==== Rate perl_memcahed memcached_fast libmemcached perl_memcahed 7163/s -- -61% -77% memcached_fast 18519/s 159% -- -41% l ibmemcached 31447/s 339% 70% -- ==== Benchmark "Simple set() (w/serialize)" ==== Rate perl_memcahed memcached_fast libmemcached perl_memcahed 3529/s -- -31% -41% memcached_fast 5086/s 44% -- -15% libmemcached 6002/s 70% 18% -- ==== Benchmark "Simple set() (w/compress)" ==== Rate perl_memcahed libmemcached memcached_fast perl_memcahed 6684/s -- -39% -63% libmemcached 10989/s 64% -- -39% memcached_fast 17986/s 169% 64% --
先ほどLibMemcached.pmの0.00003をアップロードした。このバージョンでCache::MemcachedのAPIを全て網羅したと思う。これでサクッと入れ替えができるはず!問題があったら連絡してください。

ちなみに最新ベンチマークの結果は以下の通り
daisuke@beefcake Cache-Memcached-LibMemcached$ perl -Mblib tools/benchmark.pl Rate perl_memcahed libmemcached perl_memcahed 3808/s -- -88% libmemcached 32680/s 758% --

Cache::Memcached::LibMemcachedベンチマーク

折角だからベンチをとってみた。びっくり。
daisuke@beefcake Cache-Memcached-LibMemcached$ perl -Mblib tools/benchmark.pl Rate perl_memcahed libmemcached perl_memcahed 3909/s -- -86% libmemcached 27778/s 611% --
おおおお、思ったより差がある!

ベンチマークスクリプトはcodereposに入れておいた。

Cache::Memcached::LibMemcached続き

Cache::Memcached::LibMemcached 0.00002をリリースしました。このリリースではget_multi(), decr(), incr(), delete()をサポートしてます。よりCache::Memcachedとの互換性が進んでおりますよ。

CPANにインデックスされたらこの辺りに出てきます。

Cache::Memcached::LibMemcached

これを今朝読んだのでCache::Memcached::LibMemcachedを作ったよ!
なんか用途が広そうなのでcodereposに入れました。

使い方はSYNOPSISの通り。Cache::Memcachedとほぼ一緒。まだまだ足りないメソッドがあるのでその辺はコミットしちゃってくださいw

use Cache::Memcached::LibMemcached; my $memd = Cache::Memcached::LibMemcached->new({ serves => [ "10.0.0.15:11211", "10.0.0.15:11212", "/var/sock/memcached" ], compress_threshold => 10_000 }); $memd->set("my_key", "Some value"); $memd->set("object_key", { 'complex' => [ "object", 2, 4 ]}); $val = $memd->get("my_key"); $val = $memd->get("object_key"); if ($val) { print $val->{complex}->[2] }

Text::MeCab::Dictでカスタム辞書

ちょっとリリースそのものでバタバタしてしまいましたが、Text::MeCabを使って、mecabのカスタム辞書に語句を比較的容易に追加できるようにしました。例はText::MeCab 0.20004に同梱されているeg/add_custom.plを参照してください。

自分の場合はちょっと人名をがばっと追加したかったのでAcme::Actor::JA(codereposのみ -- CPANにはアップしてません)とText::MeCab::Dictを使って3000人程の人名を追加してやりました。これをすると何がいいかというと、これまでだとものすごく有名な人の名前で検索する場合とかに「姓」「名」に名前が分けられてしまっていたところがその名前全体をひとつの語句として認識してくれるようになります。

# 追加前 shell > 堂本光一 堂本 名詞,固有名詞,人名,姓,*,*,堂本,ドウモト,ドーモト 光一 名詞,固有名詞,人名,名,*,*,光一,コウイチ,コーイチ # 追加後 shell > mecab 堂本光一 堂本光一 名詞,固有名詞,人名,*,*,*,堂本光一,どうもとこういち,*


ちなみに二つ目の読みがひらがななのはただ面倒くさかったからです。
ちゃんとやればカタカナに変換も容易でしょう。

洗濯機がご臨終

うちのHITACHI製NW-D8EX、昨日の夜ご臨終なされました。F3というエラーが出て、ぴーぴー鳴るだけでそれ以上動かない。ネットを見ると温度を感知する部品が云々書いてあったけど、そんなん言われてもそもそもその部品はどこやねん、って感じだったので今朝方HITACHIのカスタマーセンターに電話してみた。

電話対応してもらったお姉さんはもう一言目から謝りっぱなし。いや、壊したの俺だし・・・でも特になんの問題もなく修理に来てもらえるらしい。お金はもちろん取られるんだろうけどね。

Text::MeCab::Dict作った

mecabで辞書に単語を追加するのを簡単にするためにText::MeCab::Dictを作って、codereposに入れました。・・・が!まだ一回も走らせてません(笑)人柱になっていただくか、もう少々お待ちくださいまし。

Acme-Actors-JA作った

Acme::Actors::JAというWikipediaから日本語で俳優/女優リストをスクレープするモジュール作った。codereposに入れておいたよ。

Queue::Q4M

最近ちょろちょろと動かしているQ4M、Perlラッパーを作っちゃいました。
使い方はこんな感じ(SYNOPSISそのまんまだけど)

use Queue::Q4M; my $q = Queue::Q4M->connect( connect_info => [ 'dbi:mysql:dbname=mydb', $username, $password ], table => 'q4m' ); for (1..10) { $q->insert(\%fieldvals); } while ($q->next) { my ($col1, $col2, $col3) = $q->fetch(\@fields); print "col1 = $col1, col2 = $col2, col3 = $col3\n"; } while ($q->next) { my $cols = $q->fetch_arrayref(\@fields); print "col1 = $cols->[0], col2 = $cols->[1], col3 = $cols->[2]\n"; } while ($q->next) { my $cols = $q->fetch_hashref(\@fields); print "col1 = $cols->{col1}, col2 = $cols->{col2}, col3 = $cols->{col3}\n"; } $q->disconnect;
よかったら使ってくださいまし!

Q4M人柱その3

http://d.hatena.ne.jp/kazuhooku/20080108/1199756006

ちょっと反応が遅くなってしまいましたが、とりあえずお返事。

でも dmaki さんの速度はさすがに遅すぎな気もする (自分のとこだと倍くらい)
  • ディスクがいっぱいいっぱいなのかなw
60%満タン状態です。なんか自分の環境ではいくらやってもid:kazuhoさんのパフォーマンスがでないなぁ。なんでだろ。

もう一件のWHEREを使える云々はid:kazuhoさんの言った通り。具体的な条件はまたちょっと違うのですが、とにかく受け取り先のテーブルという以外の条件で次のアイテムを取り出したいのです。それができるとすごく嬉しい!

Q4M人柱その2

rev40のq4mを使ってベンチマーク。といっても単純にSELECTとINSERTのベンチのみ。
use strict; use warnings; use DBI; use Time::HiRes qw(time); my $TEST_ROWS = $ENV{TEST_ROWS} || 1024; my $dbh = DBI->connect( $ENV{DBI} || 'dbi:mysql:database=test;host=localhost', $ENV{DBI_USER} || 'root', $ENV{DBI_PASSWORD} || '', ) or die 'connection failed:'; $dbh->do('drop table if exists q4m_t'); $dbh->do('create table q4m_t (v int not null) engine=queue'); my $insert_time = 0; my $select_time = 0; my $insert = $dbh->prepare("insert into q4m_t (v) values (?)"); for (my $i = 0; $i < $TEST_ROWS; $i++) { my $start = time(); $insert->execute($i); $insert_time += time() - $start; } my $sth = $dbh->prepare("select queue_wait('test.q4m_t')"); for(0..$TEST_ROWS - 1) { my $start = time(); if ($sth->execute()) { my $h = $sth->fetchrow_hashref(); } else { last; } $select_time += time() - $start; } $dbh->do('select queue_end()'); print STDERR "$TEST_ROWS items used\n"; print STDERR " avg insert time: ", $insert_time / $TEST_ROWS, "\n"; print STDERR " avg select time: ", $select_time / $TEST_ROWS, "\n";


このスクリプトに対して、128、256、512アイテムでテスト
daisuke@beefcake q4m$ env TEST_ROWS=128 perl queue.pl 128 items used avg insert time: 0.0969786122441292 avg select time: 0.0974297747015953 daisuke@beefcake q4m$ env TEST_ROWS=256 perl queue.pl 256 items used avg insert time: 0.107754170894623 avg select time: 0.115405934862792 daisuke@beefcake q4m$ env TEST_ROWS=512 perl queue.pl 512 items used avg insert time: 0.0976005531847477 avg select time: 0.0964000821113586

俺のMac 10.5で他のブラウザとか動かしながらでこんな感じ。

うーん、queue_wait()にWHERE使えると嬉しいなぁ・・・

考え中:DSL for Gungho (or GSL)

Gunghoで今度行うプロジェクトはDBから次に取得するURLをガンガン引っ張ってくるというよりは、スクレイパー的な用途として使う事が多いようだ。そういうわけで、今度はリクエスト→レスポンスのサイクルを定義するほうが重要になってきそうだ。

なので今考えているのはGSL (Gungho-DSL)。ウマく作ればWeb::Scraperと融合もできそうな気がする。さて、以下に今考えている案を書いてみる。興味ある人いるかな?
use GunghoX::GSL; config( engine => { module => 'POE' } ); process { # Simple request. This is equivalent of saying # request { # url => 'http://search.cpan.org' # } # or # request_build { # my $req = Gungho::Request->new(GET => 'http://search.cpan.org'); # return $req; # }; request 'http://search.cpan.org'; # Handle the previous response response { my $response = shift; # do something with $response } }; process { request { name => 'BEGIN', url => 'http://search.cpan.org', }; response_for 'BEGIN', { my $response = shift; my @links = ...; # follow links foreach my $link (@links) { request { name => 'follow', url => $link } } }; response_for 'follow' { my $response = shift; # do something with $response } };

取り急ぎ"process"に代わる名前が欲しいところだな。

Text-MeCab is on coderepos

前もって告知した通り、Text::MeCabをcodereposに移動した。基本書き直しなんでまだちょっとAPI的に足りてない感じなので、コミットしてくださる方がいたら幸い。

なんじゃこりゃあ。

1/8 追記:id:miyagawaによると同梱はされてないらしい。でもどちらにしろ・・・なぁ。



ちょっ。馬鹿じゃねーの。

twitterとか見てるとtokuhirmとかとなんかあったらしいから、別にpluginとか好きに出せばいいんだけどさ、問題はなんでこれらのディストリビューションにHTTP::MobileAgentが同梱されてんのじゃ!cpan シェルからinstall HTTP::MobileAgentした時にめんどうくせえじゃんか。

仲違いは勝手にしてくれ。CPANは汚染すな。

Senna-Perl

ながらくアップデートのなかったSennaのPerlバインディングですが、今codereposで作業中。ただやっぱり時間切れになりそうな予感なので、もし今回の休みの間に終わらなかったらdev リリースとして出そうと思います。後はcodereposにあるので他の人もハックしてくれるとありがたかったり。Senna-Storageはてがつけられん!

あとはText-MeCabもcodereposに移そうかと思ってたり。

2008年元日

あけましておめでとうございます。

さて、2008年は風邪で・・・はじまりませんでした。初期状態のだった30日、31日とほぼ寝倒したので多分完治。さすがにちょっと酒は控えよう。と、思ったが、昼頃に実家に帰って飯食ってたらスパークリングワインがあるっていうんで俺と妹は酒をちびちびやりながら飯。

夜はなぜかカレー。なんも正月らしくねぇなw

妹に「勇者のくせになまいきだ」を取られたのでテレビを見ようと思ったらこの家ではチャンネル権は俺になかったので、プログラムを書いて夜が更けて行ったのだった。

Author

Daisuke Maki (a.k.a lestrrat): Perl hacker, Director of Japan Perl Association, YAPC::Asia Tokyo Organizer (2009-2012), Fluent in Japanese, English. Ex-Brazilian (sorta)

#perl #c #ruby #java #mysql #english #japanese #opensource #stf #cooking #scotch #cigar


このエントリーをはてなブックマ
ークに追加

翔泳社よりモダンPerl入門(2010)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ