ブログトップ 記事一覧 ログイン 無料ブログ開設

masutaroの日記

2013-10-28 CPANモジュールのインストールパス調べ方 このエントリーを含むブックマーク

CPANモジュールインストールパスを知りたい時、以下のようにコマンドを打つとお手軽に調べられる。

$ perldoc -lm URI
/usr/lib/perl5/site_perl/5.8.8/URI.pm

2013-07-30

プログラム変数名を考えるアドバイスツール

プログラムを書いていて、秀逸な変数名を考えるのは難しいなとつくづく思うんですが、コンセプトが素敵なサービスを見つけました。

デベロッパーのためのネーミング辞書」
http://codic.jp/

例えば「登録」とか入力すると以下のように変数名がサジェストされます。

f:id:masutaro:20130730113301p:image

マンパワーで辞書データ作っているようなので、まだまだ改善余地というかデータの充実余地があるのですが、生産性と品質に寄与する素敵サービスだなぁと思いました。

2013-06-17 ターミナル終了後もプロセスを継続させたいとき このエントリーを含むブックマーク

ターミナル終了後もプロセスが継続されるようにしたい場合、2つ方法があると知ったので覚書。

事前にターミナル終了することが分かっているとき

あらかじめターミナル終了することを分かってコマンド実行するときは、nohupをつけてコマンドを実行すればOK

$ nohup コマンド &

これで、ターミナルを閉じてもプロセスは継続される。nohupについて詳しくは、以下ページなどを参照。
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230850/

あとになってターミナル終了しないといけないことが分かった時

実行完了まで長い時間がかかるプロセスを動かしている最中に、何らかの理由でターミナルを終了しないといけなくなったようなときは、プロセスバックグラウンド実行に切り替えてからdisownすればOK

$ Ctrl + z
$ jobs
$ bg %ジョブ番号
$ disown %ジョブ番号

2011-12-23

Starletメモ

mod_perlで動かしてるコードをStarletで動くようにして、
それぞれworkerの数を10にしてab -c 10 -t 1したら、
StarletのほうがRequests per secondが3くらい多かった。

Percentage of the requests served within a certain time (ms) の結果が

ってなってるんだけど、これは半数(50%)のリクエストにおいて、
32ms程度はレスポンス速度が高速化されてるという認識でいいのかな。

HTML返すのに100msくらい高速化できたら、
mod_expiresとの上手い組み合わせでスマホとかの体感速度変わりそう。

2011-12-18

ModPerl::RegistryとModPerl::PerlRunの違いを実現してる実装を読んだ

mod_perl*1を使う際、PerlResponseHandler*2に、
ModPerl::RegistoryとModPerl::PerlRunのどちらを使うか選択肢が発生します*3

ModPerl::RegistryとModPerl::PerlRunの違い

両者における明確な違いは以下の2点です。

これを検証するために、BEGINやCHECK、INITブロックにprint文を入れ込んで、
ModPerl::RegistryとModPerl::PerlRunで挙動がどう異なるのか調べる作業を
やったことがある方もいらっしゃるかと思います。

かく言う自分も「mod_perlの実験(2) - Perlプログラムのライフサイクル」を読みながら、
ハンドラーの違いで評価の作法がどう異なるのかを検証をしたことがあります。

で、ModPerl::RegistryとModPerl::PerlRunのこれらの挙動の違いは、
XSレベルで実現されているのだとずっと思っていたのですが、
意外にもPerlレベルで、ModPerl::RegistryCookerというモジュール実装されていました。

この土日にその辺のことを勉強したので、以下で説明してみます。

違いを実現している実装部

まず、ModPerl::RegistryとModPerl::PerlRunは、
ModPerl::RegistryCookerというモジュール継承して出来ています。
ModPerl::RegistryとModPerl::PerlRunの中には実際、大した内容は書かれていなくて、
ほとんどの実装はModPerl::RegistryCookerが持っています。

ということで、以下ではほとんどModPerl::RegistryCookerの説明を書いていきます。

mod_perlではブラウザからスクリプトがリクエストされると、
ModPerl::RegistryCooker::convert_script_to_compiled_handlerの中で、
スクリプトのファイルパスを利用してユニークなパッケージ名を生成し、作ったパッケージ名で、
スクリプトの元処理を動的に以下のようにラップします*4。そして、それをevalします。

package ModPerl::ROOT::ModPerl::PerlRun::opt_local_apache2_htdocs_perl_test_2epl;

sub handler {
    local $0 = '/opt/local/apache2/htdocs/perl/perlrun.pl';

    #line 1 /opt/local/apache2/htdocs/perl/perlrun.pl
    #!/opt/local/bin/perl

    # 元々の処理がsub handler内に組み込まれる
    use strict;
    use warnings;
    use CGI;
    ・
    ・
    ・
}

さて上記の処理で、リクエストされたスクリプト
packageとして評価(コンパイル)されたことになります。

冒頭で書いたModPerl::RegistryとModPerl::PerlRunの違いは
この評価処理を1度のみとするか、リクエストの度に行うかの違いです。

2回目以降のリクエストを処理する際に、再び評価(コンパイル)すべきなのかどうか分岐する処理は、
ModPerl::RegistryCooker::default_handler()の冒頭で行われます。

具体的には、if($self->should_compile)という箇所なのですが、
ModPerl::PerlRunではこのif文が絶対に真になるように実装されていました。

ModPerl::Registryでは、ModPerl::Registry::cache_tableという、
評価済か否かの情報を保持する機構を用いて、
評価済であれば偽に、未評価であれば真になる仕組みになっていました。

sub default_handler {
    my $self = shift;

    $self->make_namespace;

    # ModPerl::PerlRunでは、絶対このif文で真になる
    if ($self->should_compile) {
        #
        # うまい説明の仕方が分からないのですが、
        # $self->should_compileにはコードリファレンスがあてがわれていて、
        # ModPerl::PerlRunでは、use constant TRUE => 1の結果が返ります。
        #
        my $rc = $self->can_compile;
        return $rc unless $rc == Apache2::Const::OK;
        $rc = $self->convert_script_to_compiled_handler;
        return $rc unless $rc == Apache2::Const::OK;
    }
# 以下省略

以上、ModPerl::RegistryとModPerl::PerlRunの評価作法の違いは、if分岐のコントロールによって成り立っていました。

余談になりますが、一般にはModPerl::RegistryとModPerl::PerlRunでは、
速度はModPerl::Registryのほうが速いと言われます。
この速度差は、前述したevalが毎回発生するかどうかのコスト差によるもののようです。

最後に

冒頭に記載しなかったのですが、実はもうひとつ、実行フェーズで行われた
requireの扱いもModPerl::RegistryとModPerl::PerlRunで異なっていて、
それも土日に勉強したのですがそれはまた別エントリで書こうと思います。

*1:ちなみにmod_perl2です

*2ApacheのResponseフェーズで呼び出されるPerlモジュールを指定するディレクティブ

*3:実際には他にも選択肢はあるし、自分でオリジナルのハンドラを実装することも出来ます

*4:/opt/local/apache2/htdocs/perl/に置かれたtest.plというスクリプトで行った場合の例です

Connection: close