2008年4月アーカイブ

奥田民生見てきた

奥田民生ツアー最終節@JCBホール。

正直そんなに民生ファンってわけでもないのだが、結構楽しめた。3月にできたばかりというJCBホールがよかったのも確実に理由の一つ。縦に3階分バルコニー席があって、奥に広がるのではなく、円筒状になっている。もはやメタリカやレイジでアリーナは懲りて、これからはジジィらしく席で座って見ることにした俺にとってはこのセットアップがちょうどよかった。

「息子」はツアー中もそんなに演奏しなかったらしいのだが、ちょうど聞けた。いい歌だね。本当のツアーフィナーレは今夜。

EC2用イメージ削除スクリプト書いた

EC2使ってると新しいイメージを作った時に毎回前のイメージをS3から消し損ねそうになる。お金がもったいないしいやんいやんなので、スクリプト書いた。

以下のように呼び出すとEC2に登録したイメージをderegister+バケットを空にする。
perl ec2-remove-image.pl -a ACCESS_KEY -s SECRET_KEY -b BUCKET_NAME -i IMAGE_NAME
ソースはこんな感じ。あんまりテストしてないから気をつけて!
use strict; use Net::Amazon::S3; use Getopt::Long; use constant EC2_DEREGISTER => "/usr/local/ec2/bin/ec2-deregister"; main(); sub main { my %options; if (! GetOptions(\%options, "access_key|a=s", "secret_key|s=s", "bucket|b=s", "image|i=s", )) { exit 1; } my $aws_access_key_id = $options{access_key} or die "No access_key"; my $aws_secret_access_key = $options{secret_key} or die "No secret_key"; my $bucket = $options{bucket} or die "No bucket"; my $image = $options{image} or die "No image"; system("/usr/local/ec2/bin/ec2-deregister", $image) == 0 or die "Failed to execute ec2-deregister"; my $s3 = Net::Amazon::S3->new( { aws_access_key_id => $aws_access_key_id, aws_secret_access_key => $aws_secret_access_key, retry => 1, } ); my $bucket = $s3->bucket($options{bucket}); my $response = $bucket->list; foreach my $key ( @{ $response->{keys} } ) { next unless ( $key->{key} =~ /image\.part\.\d+$/ || $key->{key} eq 'image.manife st.xml'); print "deleting '$key->{key}'\n"; $bucket->delete_key( $key->{key} ) or die $s3->errstr; } }

少林少女みてきた

えーと、結論から言うと、柴咲コウに萌えるための映画です。以上。カンフーハッスルと一緒で話は支離滅裂、細かい伏線は何も説明されず、とりあえずなんか話が進んでいく。

柴咲コウはとてもとても凛々しく、美しかったです。

でも以上。

*GLOB自重

Perlで*GLOBとか*{"$pkg\::foo"} = sub { .. }とかそういう書き方ができるわけです。で、これって言語上全く問題のない書き方だし、実際にstatic typedな言語では絶対できないものすごく便利な使い方があったりするんですが、これ実際には色々と制限がつきます。というか、副作用があったりなかったりする。

IRCでも言ってたんだけど、たとえばid:tokuhiromとかid:miyagawaとかid:Yappoとか、もう確実にそれがどんな副作用があるか分かった上で使っている人たちはまだいいんだけど、問題はそのコードをコピペしてしまう人たちがいるということ。コピペしてしまうのはもう人間の性なのでしょうがない。だから分かってる人こそ自重すべき。

と、#codereposとsvn経由でid:tokuhiromに因縁をつけてみたら、きれいにしてくれた、という話。

daisuke@beefcake HTTPx-Dispatcher$ svk log --limit 6 ---------------------------------------------------------------------- r52078 (orig r10420): tokuhirom | 2008-04-25 12:50:24 +0900 おこらないで!srezic! ---------------------------------------------------------------------- r52077 (orig r10419): tokuhirom | 2008-04-25 12:46:28 +0900 これならいいんじゃないのかな! ---------------------------------------------------------------------- r52076 (orig r10418): tokuhirom | 2008-04-25 12:43:07 +0900 黒魔術レス ---------------------------------------------------------------------- r52075 (orig r10417): daisuke | 2008-04-25 12:40:00 +0900 Exporter使わない版 ---------------------------------------------------------------------- r52074 (orig r10416): daisuke | 2008-04-25 12:27:27 +0900 あたらしめのExporter必須 ---------------------------------------------------------------------- r52073 (orig r10415): daisuke | 2008-04-25 12:26:58 +0900 Globでガボガボするのをやめてみる ----------------------------------------------------------------------

Crypt::DH::GMP is now safe on Debian

Debianでなんか問題がでていたCrypt::DH::GMPですが、昨日作った0.00004で問題を解決しました。普通に文字列が1文字分足りてなかった。くそ。なんでFreeBSDで起こらないのか不明

で、今日はpub_keyとcompute_keyのそれぞれをバイナリ+バイト単位での0パッドという形でMath::BigIntではなく直接文字列を作成するpub_key_twocとcompute_key_twocを追加した0.00005を作った。あとはGMPHack.pmというモジュールを作っているので、これを使ってNet::OpenID::Consumerを外部から変えてしまおう、というもくろみ

Perl5 C Functions You Don't Know About

Perl5は実にさまざまな環境で動く。すると当然だが、C/XSでコードを書くときはその辺りも考慮にいれつつコードを書くのが良い。

File::MMagic::XSはApacheもmod_mime_magicをXSから直接使えるようにポートした物だ。これをPerl用にポートするとなると当然APRが使えないので環境の差を吸収してくれるレイヤーがなくなってしまう。んじゃあそのままCの関数使えばいいのかというと・・・Perl5がすでに吸収してくれるところが結構おおいのだな。

perldoc perlclibとすると、その辺りのC関数→Perlの内部関数の対応表を出してくれる。

が。書いてないものもある。そういうのはperlのソースコードを展開したところで.hファイルを色々grepしてるとでてくるので積極的に使っていくといいと思う。ちなみに今回そもそもこのエントリを書こうと思ったのはstat()に対応する関数はないのかと思って探してみたからだ。そしたらStat()というものを発見。S_ISDIR()とか、そのまわりの処理も結構マクロがかかれていて便利

あと、Perl API自体もバージョンによってちょっぴり違う事があるので、そういう時はDevel::PPPortを使ってppport.hを作成するといい。このppport.hはマクロでバージョン毎の違いを吸収してくれるとともに、その差異に該当する構文がディストリビューション内に存在するのかどうかをチェックしてくれるPerl スクリプトでもある:
perl -MDevel::PPPort -e 'Devel::PPPort::WriteFile()' # ppport.h作成 perl ppport.h # 実行!

あとは表示される診断結果に従って、#defineをファイルに入れていくだけ。便利よ!

NetApp Focus 2008に行ってきた。

書くの忘れてた。NetApp Focus 2008に行ってきました。NetAppは自分の古巣でもありますし、特にS3とか、仮想ストレージが台頭しつつある昨今、どんな戦略をとっていくのか興味もあったのです。

まずとほほに感じた点。いろんな人がプレゼンしてたけど、正直あれじゃあ寝る。普段YAPCやShibuya.pmで見てるプレゼンターたちの能力の高さが伺えた。本当に期待していたのはベンダーやクライアント会社の方たちのプレゼンで実際のユースケースでどういう工夫をしたか、なんだけど、なんか全然要旨を得ないし・・・。む〜ん。

NetApp経営陣は相変わらずの明瞭の歯切れだった。まぁこの辺は好き嫌いが分かれるところだろうな。あとはyazさんの話がおもしろかった。半分くらいは内部の人だった自分はわかることなんだけどね。yazさんはなんか偉くなってました(見かけが)。あ、なんとかマネジャーっていう肩書きになっていたので本当に偉くなってたみたいです。

しかし最初のまともな仕事がこの会社でよかったよ。ちゃんとしたエンジニアリングを教えてくれて。

で、NetAppも今後は仮想化していく方向のようだ。WAFLだけ超低価格で売ってくれないかなw


自己啓発本

自己啓発本って世にあふれてるけど、ほんとにそんなにみんな好きなの?ためになってるわけ?自己啓発本をまぁ参考に、ってのはなんとなくわかるんだけど、でも所詮他人のノウハウじゃない。その人のノウハウって本当にあなたに有効?

まぁそれはためになる新発見もあるとは思うけど、自己啓発本は読む=成功をイメージさせるマーケティングを行っているので、基本的なところで「つけるだけで幸せが訪れるパワーストーン」的な商法と同じだって事はどこかでわかってたほうがいいと思うんだよな。

まぁいいんだけどね。自己啓発本を参考にした、っていう成功者を見たことがないもんで、メディアとかでの取り上げ方を見てたりするとどうも、ね。

ご飯を作るのは楽しいが、大変なんだよ。

結婚九ヶ月で離婚宣言」についての発狂小町を流し読みしたわけだが、この一言がすげぇ

「夫は、基本的には女が家事をするべきだけど、専業主婦ではない以上、最低限週一回でも夕飯を作れば、良くできた妻だと認めてくれる」そうです

・・・ってどんだけ上から目線!

いやあ、基本女性がご飯を作る作らないはこの際置いておいて、旦那のほうはたぶん一人暮らしとかしたことねぇんだろうなぁ。仕事しながら飯を作るには冷凍とかそれなりの工夫が必要だし、ともかく大変なんだよ!

自分だけが食べるならかなりの手抜きもできるんだけど、この旦那の場合はなんやかんやいいそうだしなぁ。作ってくれるだけいいじゃん。っていうか自分で作れよ。

ちなむと、「おいしい」と言うのを強要する人も嫌だ。まずいものはまずいんだ。「まずい」とは言うのはあれだけど、やんわりと言われたら、もっとうまくなろうよ。まぁその前に感謝の気持ちがないと難しいだろうが(というわけでいたちごっこ)

Memcached::libmemcachedでリーク発見

Memcached::libmemcachedでリークを発見しました。子クラスであるCache::Memcached::libmemcachedもその影響を受けます。以下のようなコードを書くとすぐわかるのですが、DESTROY()が毎ループではなく、global destruction時まで起きません。
for( 1..100) { my $cache = Cache::Memcached::libmemcached->new( { ... } ); }
これは単純にSV -> SV間のコピーをする時にSvREFCNT_incを呼んでしまうコードがMemcached::libmemcachedのコンストラクタにあったからです。sv_2mortal()することで解決しました。

報告してコミットした時にTimはちょうど寝る寸前だったのでリリースはまだもう少し先になりそうですが、待てない方はsvnから最新版を入手してください:
http://perl-libmemcached.googlecode.com/svn/trunk

Benchmark::ProgressBar

Benchmark::ProgressBarというものを書きました。

追記:id:tokuhiromがほぼ同じ物を書いていたんだが、俺がsvk importしたらそのまま上書きしたらしいよ

長い時間かかるベンチマークを待つのが苦痛で苦痛でしょうがなかったので、なんとかしてプログレスバーを出したかったのです。

で、元々はこういうコードだったのを
use strict; use Benchmark qw(cmpthese); use Crypt::DH; use Crypt::DH::GMP; .... { print "Benchmarking instatiation cost...\n"; cmpthese(500, { pp => sub { Crypt::DH->new(%args) }, gmp => sub { Crypt::DH::GMP->new(%args) }, } ); }
こういうふうにすると:
use Benchmark::ProgressBar qw(cmpthese); # あとは一緒
こんな感じでプログレスバーが出るようになります。
Benchmarking instatiation cost... gmp: 35% [======================== ]
あら素敵☆なんとなくいつ終わるかわかるわ!

コードはめちゃくちゃ汚いです。まねしてはいけません。

Crypt::DH::GMPの続き

Crypt::DHは基本3つのフェーズからなっていて、
my $dh = Crypt::DH->new( p => ..., g => ... ); $dh->generate_keys(); $dh->compute_key( $some_public_key );
という3つのことをすると作業完了となる。で、tools/benchmark.plを書き直してこのフェーズ毎にベンチマークを取ってみた。結果はこんな感じ
perl tools/benchmark.pl Benchmarking instatiation cost... (warning: too few iterations for a reliable count) Rate gmp pp gmp 223/s -- -98% pp 10000/s 4380% -- Benchmarking key generation cost... Rate pp gmp pp 3.42/s -- -99% gmp 435/s 12621% -- Benchmarking compute_key cost... Rate pp gmp pp 3.39/s -- -99% gmp 370/s 10825% --
最初の初期化・インスタンス作成に関しては圧倒的にCrypt::DHのほうが速い。これは単純にCrypt::DH::GMPではnew() -> xs_new()というメソッドディスパッチをしてるからだと思う。

その後のgenerate_keys()およびcompute_key()に関しては圧倒的にGMPが速い。

ただし、上記はそれぞれの値を「文字列として」処理した場合の話だ。Crypt::DHはこれらの値をMath::BigInt形式で受け渡しするため、それぞれの値をMath::BigIntへ変換しないといけない。で、ここでまた遅くなる。

Crypt::DH::GMP::Compatはその部分の差異を吸収するためのモジュールだが、これだと実質パフォーマンス改善は数パーセントで、あまり意味がない(やってみたら5%から10%くらいだった)。だからNet::SSH::Perl とかを速くするには多少ソースコードに手を加える必要があるね。

Crypt::DH::GMPを作った

id:tokuhiromにそそのかされれてCrypt::DH::GMP (リンクはそのうち出現します)書きました。Crypt::DHってモジュールがあって、これに依存するモジュールが少々あるわけですが、このモジュールがすこぶる遅いわけですな。なんで遅いかというとこのモジュールは裏でMath::BigIntを使っているから。Math::BigInt自体はいわゆる任意精度数演算ライブラリで、これをポータブルな方法でPerl上で動作させるにはとてもよくできたモジュールです。

が。遅い。

裏でlibgmpやPari等を使っても、それでも遅い。その理由は単純で、Math::BigIntを使うと裏で何回も何回もSV -> mpz_t -> SV等の変換を含めた、「Perlらしい手法が実現できるための処理」が行われるからです。

Crypt::DHのソースコードを読む限り、Crypt::DHが行っている計算はたいしたことではない。だったら、普通にC structの中にmpz_t構造体を何個かもって、それらを使って直接GMPで計算したら速いんでないの?というのが今回のモジュールの趣旨です。まぁ、このモジュールだとlibgmpが必須になるから敷居が高くなるんだけど、どうせ実用的なレベルで計算を行うにはlibgmp必須だし、いいじゃん?ということで作ってみた。ちなみにソースコードのほとんどは半蔵門線車内の渋谷→大手町間で書いたよ!

さて、とりあえずうごくようになったのベンチマークを・・・と思ってベンチマークを動かしてみたら、これが遅い遅い。なんじゃこのスピード。全く話にならないので、ベンチを5000回から100回まで落としてみたらとりあえず走った。
daisuke@beefcake Crypt-DH-GMP$ perl -Mblib tools/benchmark.pl Rate pp gmp pp 1.70/s -- -98% gmp 112/s 6526% --
まぁ、速いことは実証できたかな。長いベンチマークは寝てる間にでも走らせておく。

あと、Crypt::DHはMath::BigIntオブジェクトを返すようになっているので、そのあたりの互換性を保つために-compatオプションを指定できるようにしておいた。以下のようにしておくと、今までのCrypt::DHを使っているモジュールでもCrypt::DH::GMPを使える・・・はず。
use Crypt::DH; use Crypt::DH::GMP qw(-compat);
まだちゃんと使ってないので人柱歓迎です。

旅行中作業

2年ぶりに京都旅行してきた。が。やっぱりとこかしこで作業してしまった。

で、Catalystでいうところの$class->config()が欲しかったので新幹線に乗ってる間に別パッケージにしてアップした。あと同じく新幹線の中でCache::Memcached::libmemcachedもバージョンアップしておいたよ

walk_stats()を書いたよ

Memcached::libmemcachedにはstats()相当のものがないのだけれども、Cache::Memcached::libmemcachedではそれを実装しようと思ってMemcached::libmemcachedのほうにwalk_stats()というメソッドを足しました。それが実装されているバージョンの0.1901が昨日の夜にアップされた模様。

これはサブルーチンを渡すと、STATSコマンドを発行して、そのそれぞれの値に対してそのサブルーチンを実行します。ハッシュとかにつっこみたかったらその関数内でやるといいよ!

実際には俺がコミットした後にTimがだいぶ手を入れてくれた。tim++

Coro-4.49がコンパイルできないとお嘆きの皆様

追記:これ書いて、バグレポートしたとたんに4.50をかましてくれたよ。mlehman++。(まだコンパイル通るかどうかみてない)

このパッチで通ると思うよ。たぶん作者がperl 5.8でテストするの忘れてるだけだと思われ。ちなみに最初のPL_parser云々はたぶんそのまま消しちゃっても大丈夫。
--- Coro-4.49/Coro/State.xs 2008-04-07 02:47:38.000000000 +0900 +++ Coro-4.49.hacked/Coro/State.xs 2008-04-10 17:29:34.000000000 +0900 @@ -738,7 +738,7 @@ PL_localizing = 0; PL_dirty = 0; PL_restartop = 0; -#if !PERL_VERSION_ATLEAST (5,10,0) +#if PERL_VERSION_ATLEAST (5,10,0) PL_parser = 0; #endif @@ -1132,7 +1132,7 @@ croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states"); #if !PERL_VERSION_ATLEAST (5,10,0) - if (expect_false (PL_lex_state != LEX_NOTPARSING) + if (expect_false (PL_lex_state != LEX_NOTPARSING)) croak ("Coro::State::transfer called while parsing, but this is not supported"); #endif }

CoroでFlickrにアクセスする

もうずいぶん前からCoroを使いたくて使いたくてしょうがなかったのだが、やっときたよ。Flickr APIを叩いて、非同期I/OしながらCoroで写真の情報をダウンロードするよ!

まず某sukebeさん作のWebService::Simpleを使ってみるよ(本当に使ったコードは違うフレームワーク用にいろいろついてたので、あまり利便性とか考えずに説明用のコードだけ書きだします)
package MyFlickrModel; use strict; use WebService::Simple; my $webservice = WebService::Simple->new( \%必要な引数 ); # 写真のIDを渡すとinfo, context, sizes, permsを全部ひっぱってくる sub find_photo { my $class = shift; my $photo_id = shift; my %photo; foreach my $type qw(info context sizes perms) { my $method = "find_photo_$type"; $photo{$type} = $class->$method($photo_id); } return \%photo; } # infoをひっぱってくる sub find_photo_info { my ($class, $id) = @_; my $response = $webservice->get( { method => "flickr.photos.getInfo", photo_id => $id } ); # エラーチェックとかはしょってます return $response->parse_xml; } # あと同じようにcontext, sizes, perms用の関数を書く # で、よびだす MyFlickrModel->find_photo( $photo_id );
でもこれだと写真1個につき都合4回、順番にFlickr APIを叩かなくちゃいけないね。そんなに待ちたくないんだな。非同期にしたいじゃん?で、ここでCoroですよ
Coroはcoroutineの実装をPerl5上でするわけですな。で、ちょっとハックだけれども、LWP::UserAgent系のモジュールの中身も適当にいじってくれるモジュールも用意してくれている。なのでそこらへんをまず追加:
use Coro; use Coro::Event; use Coro::LWP; use WebService::Simple; # 必ずCoro::LWPのあとに
で、先ほどのfind_photoをちょっと書き換える。ほんとにちょっとですよ?
sub find_photo { my $class = shift; my $photo_id = shift; my %photo; my @coros; # Coroを取っておく foreach my $type qw(info context sizes perms) { push @coros, async { # ここを別Coroに切り分ける my $method = "find_photo_$type"; $photo{$type} = $class->$method($photo_id); }; } $_->join for @coros; # Coroが終了するのを待つ return \%photo; }
以上! これだけで、10個の写真を検索→その後find_photo()で詳細を取得、というのが単純に17秒弱から5秒強に減った。Coroすげぇ

ちなみに同じことをしつつ、Cache::Memcached::libmemcachedでキャッシュすると0.2秒で終わるよ!

パワーナップはすばらしい

Power Nap - 要は昼寝だけどな。

5分から20分、一瞬だけ深く深く寝る。だらだらと寝ない。これだけのことだが、これが効く。このあとその数分で3時間はばりばり動ける。

まぁこればっかりは人それぞれだろうから「パワーナップするといいよ!」って言ったところでできない人はできないだろうけど、短時間の睡眠を得られる人は下手に徹夜みたいなことをするよりさっさと寝たほうがいいと思うんだ。

ってことで、6時半から起きてて、8時過ぎに5分寝てすっきりした俺様でした。

P5P にmelmaのスパムが

P5Pにスパムがきていた。日本語だ。melmaだ。リンク先はちょっと文字化けしているが、内容は「キツイ口臭で、嫌われていませんか?」だってさ。

日本人の恥さらしだからやめてくれよ。

MacBookのファンがうぜぇ

ちょっと前から急にMacBookのファンがうるさくなってて、どうしたんだと思ってたんだけど、とりあえず放っておいた。が、先ほどとうとう我慢の限界をすぎたのでどうにかすることに。

ちょっと前にdaemontoolsが悪影響あるのは学習済みだったので、まずtopで何が問題なのか見てみたら"mds"と"mdworker"というプロセスがCPU稼働率のほとんどを奪っていた模様。ぐぐってみるとどうやら微調整が可能なようなので 環境設定>Spotlightの「プライバシー」にいろいろ足してみたが、それだけでは何も変わらず。

もう少々ぐぐってみるとmdutilというコマンド発見どうやらSpotlightのインデックシングをコントロールできるらしい。これで書いてあったmdutil -i off /してみたらファンが止まった。おお!でもこれだとSpotlightが使えないってことなので、ほかのところに書いてあったmdutil -E /としてみて、今までのインデックスを破棄して、もう一回mdutil -i on /してみたところ、今度はmdsが動いているにも関わらず動いた。

・・・と思ったらこれを書いている先からまたmdsがキックしてCPUの6割〜すべてを占拠している。ええーい、offにするしかないのか?

どこの組の者でしたっけ

先日なじみのバーに行ってきたのですが、その後スタッフのO沢くんが合流する予定だったのでマスターにその旨を伝えたのです

「うちの事務所の若いのがあとでくるから」

・・・言ってから気づきました。どこのヤクザだ、これ。しかも俺と会ったことのある人なら知ってる通り、俺は丸刈り、最近はひげボーボーです。どちらかというといかつい顔つきしてます。そんなのがこんな台詞言っちゃいけないな。

すぐ気づいて何か言おうと思ったんだけど、そのままマスターはひっこんでしまったので言う機会を失ってしまった。

次回から気をつけます。

濱田屋のパンは時々微妙だと思いつつ皇居へ

今日は天気もいいので朝から濱田屋さんでパンをいろいろ買ってきて皇居まで。半蔵門でおりて大手門のほうまでてくてく。大手門あたりの公園内にある広場で食べたのだが、そこの中にある会場で結婚式をやっていた。ガラス張りの建物だったのだが、ちょうど新郎新婦の後ろ(来賓にむかってるじょうたい)から式を見る感じになってた。スタッフがバタバタしてるのが正直笑えた。

ところで濱田屋さんのパンはとにかくうまいのだが、その中にも微妙なものがある。この店にはいわゆる「お総菜系」のパンが常時5種類くらいある。その内容というのがどれもこれも和食系の総菜なわけだが、これが「きんぴらごぼう」とか「卵ほうれんそう」とか「春のそぼろ」とかなんかごはんのおかずならいいんだろうけど、パンにはどうなのよ、みたいなのが多くてとにかく微妙なのだ。

ここのクロワッサン、食パン、クルミパン、その他もろもろはとにかく抜群にうまいのに。なんでこんな微妙な味のものをいつもずっと出してるんだ。よくわからんなぁ。
HTTP::MobileAttributeの最適化祭りに突発的に参加してみた。

正直言うと未だにHTTP::MobileAttributeの中身であるClass::Componentを分かってない。なのでできることも限られてるわけだが。

今回のミニ祭りを見ていてよくわかるのは結局のところスピードに最も影響があるのは端的なコードの書き方ではなく構造(ストラクチャ)を見直す事であるというだ。id:tokuhiromのところでパフォーマンスチューニングの結果を追ってる人はわかると思うけど、結局俺が参加したのはもう本当にコードの書き方をチューニングするというレベルのところで、例えばループをアンロールしてif/elseで実装してみるとかね。でもそこはどんなにがんばっても数%のパフォーマンスゲインにしかならない。

だが、例えばプラグインの読み込みのタイミングを変える事や、Class::Componentの中身をいじってメソッドの呼び出し回数を変えてみるというようなそもそもコードの構造が変わるようなところをいじると10%~20%でパフォーマンスが変わってくる。

今回はベンチマークを取りつつ、perl -d:DProf hoge.pl && dprofppの結果を見ながら最適化できるところを追って行ったが、それでもこんな感じだ。例えばinstance_clear()というメソッドがあったのだが、これをいくら速く実装してもせいぜい2%の最適化。だが、そもそも構造を変えてこのメソッドをいらなくすれば10%くらいスピードが違ってくる。

さて激しく既出だが、これから得られる教訓は
  1. 最適化はDevel::DProfやBenchmarkを使って、最適化のポイントをまず見つけてから最適化する
  2. 細部の最適化でスピードがあがらない場合はそもそもの構造が問題な事が多い
  3. 最適化の極意は「どれだけ速く計算するか」ではなく「どれだけ計算をせずに済ますか」
  4. id:tokuhirom, id:Yappo, それに俺が3人がかりで数時間ハックするだけでパフォーマンスが数倍あがるんだから、最初から最適化なんて考えてやるより、遅くともまずアイデアを実現するほうがはるかに効率的。
  5. テストがなきゃ最適化なんて怖くてできない
あたりだと思います。

4はプログラミングに慣れてくればくるほど気をつけなければいけないところだ。最適化を気にするあまりまだちゃんと動いてもいないのに、先に最適化をしてしまう/考えてしまうような事をしているとコードがそもそもかけなかったり、コードがガタガタになったりするので要注意。

5は言わずもがな。そもそも構造に問題がある可能性がある状態なので、最適化する時にコードをぶっ壊してたらもともこもない。実際今回自分も何回も最適化の途中でコードをぶっ壊したけど、id:tokuhiromが先にいっぱいテストを用意してたから問題なかった。

そして今朝起きてみたら普通にパフォーマンスが昨夜俺が残した部分から50%くらいあがってた。素晴らしすぎる。

今朝のDProfを見る限り、あとはClass::Componentの一部とかくらいしか問題がないように思える。

# 私信:Class::Component::__ANON__が結構上にあがるんだけど、DEBUGモードかなにかの時だけにSub::Name使って動的に生成される関数に名前をつけることは可能だろうか?

Alien::MeCabを書いてみた

Cライブラリに依存するPerlモジュールを書く事が多いのでAlien::MeCabを書いてみた。これはAlien::SVNとかのようにCPANからPerlではないエクステンションをインストールするためのもの。

懸念事項:
  • すでにインストールされている時のどうさがあやふや。今はユーザーに確認した上で上書きするようにしてる
  • mecab-ipadicもインストールすべき
  • Win32での挙動を全然テストしてない
パッチ、テスト、なんでもウェルカムです。
やばいやばい。

にぽたんの記事からリンクされているのに俺の一番最近のエントリが「菓子パン」じゃ駄目だこりゃ。えーと。技術的な話書く。えーとテストはいいです。CatalystはCatalystConに参加するよ!話きくだけだけど。最近C++とCをなんか書いてます。つかPerlのコアに手入れたい気もする。gitがちょっとだけラブリー。昨日Encode::Argvってアップした。Alien::MeCabっての書こうと思ってる。

うわー、ネタないよ。IT Mediaから来た人達ごめんね、たまにしかマトモな事が書いてないブログなの、ここ。

やばいやばい。

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)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ