June 2010

June 18, 2010

このエントリーをはてなブックマークに追加
弊社の、とあるエンジニアだけが集まるミーティングで、毎週ライブコーディングでアルゴリズム勝負をやるみたいなコーナーを設けてたりします。
毎週ベンチマーク対決をやり、最強のやつに勝てるアルゴリズムで挑戦します。
#!/usr/local/bin/perl

use strict;
use Benchmark qw(:all);

my @args = qw(foo bar baz);

cmpthese(100000, {
    champ => sub { champ(\@args) },
    yours => sub { yours(\@args) },
});

# winner
sub champ {
    my $args = shift;
    # do something
}

# your code here
sub yours {

}
実際のものはもっと数多くのベンチマークのパターンがあるのですが、こんな感じの雛形があって、champ() の中身は憎き歴戦の猛者が。
その猛者に対抗し得るコードを、衆人環視の中 yours() のブレースの中に書かなくちゃいけないとか。だいぶ厳しいですね。

実際の格闘技などのチャンピオンシップなどとは違って、猛者は体調の変化や衰えなどとは縁がないので、挑戦が遅くなれば遅くなるほど段々と勝ち目が無くなっていくのですが、それでもみんな、事前にチャンピオンに勝てる方法を何とか編み出してきます。
真面目かっ!

ここ最近は、糞真面目に書いても勝てず、少し (良い意味での) ズルをしないと勝てないようになってきて、回を重ねるごとにみんながどんどんと挑戦することに萎えていくムードが蔓延しているので、新機軸として「XS なら勝てるかも?」とか、バカな考えを起こし、挑戦してみることにしました。

でも、事前の仕込み禁止のライブコーディングで、yours() のブレースの中に XS を書いて、ビルドしてから走らせるとか、だいぶ厳しい条件があり、そんな中、何とか苦肉の策としてこんなコードを書いてみました。
sub yours {
    return Foo::bar(shift);
    BEGIN {
        push @INC, qw(Foo/blib/lib Foo/blib/arch);
        my $use = sub { eval qq{ use $_[0]; }; return $@ ? () : 1 };
        unless ($use->('Foo')) {
            warn $@;
            if (-d 'Foo') {
                system(qw(rm -frv Foo)) && die $^E;
            }
            system(qw(h2xs -A -n Foo)) && die $^E;
            chdir 'Foo' or die $!;
            open my $xs, '>', 'Foo.xs' or die $!;
            print $xs <<'XSUB';
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

MODULE = Foo PACKAGE = Foo

SV *
bar(args)
    SV *args
CODE:
    // do something
OUTPUT:
    RETVAL
XSUB
            close $xs;
            (system($^X, 'Makefile.PL') || system('make')) && die $^E;
            chdir '..' or die $!;
            $use->('Foo') or die $@;
            # print "-" x 50 . "\n";
        }
    };
}
一回目はビルドが走りますが、BEGIN { } ブロックの中で実行されるのでベンチマークに影響を与えないというズルさもあいまって、何とかウマいこと動きました。良かった良かった。

なんかこれをもうちょっとキレイにやれば XS をインラインで書けたりするんじゃないか→あれ?そういえば、こういうのをやる Inline::XS みたいなのって無いのかなぁ?とか思ったのですが、どうも無いっぽいですね。
InlineX::XS というのはあるけど、これは Inline::C ベースのモジュールを XS に変換するもののようで、残念。

そもそも Inline::C で書けば良かったんじゃね?とかいう話もありますが、XS のほうがちょっとニッチでヒップな気がした中二の初夏。

今年の夏も暑くなりそうですね。


nipotan at 17:50 | Comments(0) | TrackBack(0) | 技術 
このエントリーをはてなブックマークに追加