2009年2月アーカイブ

2009年2月28日
| コメント(0) | トラックバック(0) Web::Scraperに入門した

かなーり今更感がありますが。
モジュール自体は、大分前にウェブにあったスクリプトをコピペして使ったときにインストール済みでしたが、なんとなく難しそうで敬遠していたところもありました。
が、やってみると簡単かつパワフルなモジュールであることがわかりました。

参考:use Web::Scraper; - 今日のCPANモジュール

XPathがなかなかわからないのですが、CSSセレクタでもいけるのが超絶簡単です。
例えば、aタグのhref属性を取得する場合のprocessは以下のとおり。

process 'a', 'urls[]' => '@href';

で、この場合だと、href属性がないaタグも対象になってしまうので、未定義(undef)が入る場合があります。
なので、href属性があるものだけを対象としたのが以下のprocessです。

process 'a[href]', 'urls[]' => '@href';

同じものをXPathで書くと以下のとおり。

process '//a[@href]', 'urls[]' => '@href';


で、リンクをたどる場合は画像を取得するのが基本(?)なので、そういうスクリプトを書いてみました。
…何番煎じかわかりませんが。

RSSもいいけど、今後のことを思えばAtomも欠かせません。
ざっくりとCPANを漁っていくつか見繕ってベンチマークしました。
ついでにXPathでAtomを解析してみました。
いまいち納得はいきませんが、とりあえず同じ出力を得ることができたので良しとします。

Benchmark: running Data::Feed, XML::Atom, XML::Feed, XML::FeedPP, XML::LibXML for at least 3 CPU seconds...
Data::Feed:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 413.88/s (n=1300)
 XML::Atom:  3 wallclock secs ( 3.20 usr +  0.00 sys =  3.20 CPU) @ 525.76/s (n=1684)
 XML::Feed:  3 wallclock secs ( 3.28 usr +  0.02 sys =  3.30 CPU) @ 415.23/s (n=1369)
XML::FeedPP:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @ 120.49/s (n=384)
XML::LibXML:  3 wallclock secs ( 3.16 usr +  0.05 sys =  3.20 CPU) @ 1105.81/s (n=3543)
              Rate XML::FeedPP  Data::Feed   XML::Feed   XML::Atom XML::LibXML
XML::FeedPP  120/s          --        -71%        -71%        -77%        -89%
Data::Feed   414/s        243%          --         -0%        -21%        -63%
XML::Feed    415/s        245%          0%          --        -21%        -62%
XML::Atom    526/s        336%         27%         27%          --        -52%
XML::LibXML 1106/s        818%        167%        166%        110%          --

Atomは「Perl - Google ブログ検索」な感じの10件です。

結果から見ると、やはりXML::LibXMLの一人勝ち。XPathさえきっちり書くことができるなら、これを使うのが良いでしょうね。
XML::Atom(実際はXML::Atom::Feedですが)は、PPを除いた他の二つよりは少し速いです。これはAtomに特化しているからかもしれませんが。
XML::FeedとData::Feedはほぼ同じ程度でした。
また、XML::FeedPPは残念な結果でした。しかし、Atomだから遅いというわけではなく、LibXMLとの比較だと同じ程度なので、単に比べたモジュールが高速なものが多かった、ということでしょう。

ソースは以下のとおり。

ソースだけでなくタイトルもパクリですが。
実行結果は環境によって変わるんでしょうか。
それとも、何らかの速度改善が行われたのかもしれません。

参考:XML::Simple におけるパーサーの実行速度比較 - naoyaのはてなダイアリー

Benchmark: running XML::LibXML::SAX, XML::Parser, XML::SAX::Expat, XML::SAX::ExpatXS, XML::SAX::PP for at least 3 CPU seconds...
 XML::LibXML::SAX:  3 wallclock secs ( 3.03 usr +  0.00 sys =  3.03 CPU) @ 20.79/s (n=63)
      XML::Parser:  3 wallclock secs ( 3.11 usr +  0.01 sys =  3.12 CPU) @ 57.30/s (n=179)
  XML::SAX::Expat:  3 wallclock secs ( 3.27 usr +  0.00 sys =  3.27 CPU) @ 18.38/s (n=60)
XML::SAX::ExpatXS:  3 wallclock secs ( 3.30 usr +  0.00 sys =  3.30 CPU) @ 67.33/s (n=222)
     XML::SAX::PP:  3 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @  4.00/s (n=13)
 
                    Rate XML::SAX::PP XML::SAX::Expat XML::LibXML::SAX XML::Parser XML::SAX::ExpatXS
XML::SAX::PP      4.00/s           --            -78%             -81%        -93%              -94%
XML::SAX::Expat   18.4/s         360%              --             -12%        -68%              -73%
XML::LibXML::SAX  20.8/s         420%             13%               --        -64%              -69%
XML::Parser       57.3/s        1333%            212%             176%          --              -15%
XML::SAX::ExpatXS 67.3/s        1584%            266%             224%         18%                --

使ったRSSファイルは前回と同じです。

なんともコメントしにくいです。
参考にした記事は、3年前半ほど前のものなので色々と変わっているとも言えるし、Windowsという環境のせいとも言えるし。
まあ、それにしても、XML::Parserが無難に速いことは間違いなさそうですね。

ソースコードは以下のとおり。

色々と触発されてやってみた。

参考:
Perl で XML の処理はどれが速いかベンチ : NDO::Weblog
iandeth. - XML::Simple は遅い説における意外な落とし穴
XML::Simple におけるパーサーの実行速度比較 - naoyaのはてなダイアリー

Benchmark: running XML::FeedPP, XML::LibXML, XML::RSS, XML::RSS::LibXML, XML::RSS::Parser, XML::RSSLite, XML::Simple, regexp for at least 3 CPU seconds...
     XML::FeedPP:  2 wallclock secs ( 3.02 usr +  0.00 sys =  3.02 CPU) @ 55.37/s (n=167)
     XML::LibXML:  3 wallclock secs ( 3.25 usr +  0.02 sys =  3.27 CPU) @ 496.02/s (n=1620)
        XML::RSS:  4 wallclock secs ( 3.27 usr +  0.00 sys =  3.27 CPU) @  2.76/s (n=9)
XML::RSS::LibXML:  4 wallclock secs ( 3.25 usr +  0.00 sys =  3.25 CPU) @ 49.54/s (n=161)
XML::RSS::Parser:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19 CPU) @  3.76/s (n=12)
    XML::RSSLite:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 112.10/s (n=352)
     XML::Simple:  3 wallclock secs ( 3.14 usr +  0.00 sys =  3.14 CPU) @ 61.13/s (n=192)
          regexp:  4 wallclock secs ( 3.28 usr +  0.00 sys =  3.28 CPU) @ 6340.14/s (n=20802)
 
                   Rate XML::RSS XML::RSS::Parser XML::RSS::LibXML XML::FeedPP XML::Simple XML::RSSLite XML::LibXML regexp
XML::RSS         2.76/s       --             -27%             -94%        -95%        -95%         -98%        -99%  -100%
XML::RSS::Parser 3.76/s      37%               --             -92%        -93%        -94%         -97%        -99%  -100%
XML::RSS::LibXML 49.5/s    1697%            1216%               --        -11%        -19%         -56%        -90%   -99%
XML::FeedPP      55.4/s    1909%            1371%              12%          --         -9%         -51%        -89%   -99%
XML::Simple      61.1/s    2118%            1524%              23%         10%          --         -45%        -88%   -99%
XML::RSSLite      112/s    3967%            2878%             126%        102%         83%           --        -77%   -98%
XML::LibXML       496/s   17894%           13078%             901%        796%        711%         342%          --   -92%
regexp           6340/s  229906%          168336%           12698%      11350%      10272%        5556%       1178%     --

読み込んだRSSファイルは、「はてなブックマーク - タグ - 石原さとみ(タグ「石原さとみ」を含む新着エントリー)」な感じの20件です。

正規表現はパターンがちがちで応用は利きませんが、速さはピカイチ。
XML::LibXMLはXPathがよくわからないのでアレですが、使いこなせれば速さも申し分なしです。
XML::RSSLiteが結構頑張っている印象ですね。関数呼び出しなのが、この中では違和感ありますが。
XML::Simpleのパーサーは、無難にXML::Parserを指定することでそれなりに速いです。ただ、手元の環境だとXML::SAX::ExpatXSが最速だったのですが。
ま、環境によるんでしょうね…。
XML::FeedPPがかなり健闘していると思います。ファイル構成もシンプル(1枚だけ)だし、汎用性もあるし、レンタルサーバーにも最適でしょうね。
これからRSSなどを扱うならXML::FeedPPが便利でしょうね。

ソースコードは以下のとおり。
使う場合はRSSファイルを適宜用意してください。

名前付けに困っていたところに、CPAN 長いネームスペース大会 - にぽたん研究所CPAN 階層の深いモジュール王選手権 - id:kazuhookuのメモ置き場をみて、CPANモジュールからアイデアをもらおうと思ってやってみた。
とりあえず1000回以上使われていたのは以下の名前。
(2009/02/20時点)

 3060 times: Net
 2581 times: XML
 2287 times: Plugin
 1964 times: Bio
 1743 times: Data
 1696 times: HTML
 1427 times: API
 1346 times: WWW
 1310 times: Test
 1296 times: Class
 1176 times: eBay
 1140 times: Apache
 1105 times: DateTime
 1083 times: Text

さすがに、Net,XML,HTML,WWWなど、ウェブ関係が多いようです。
あと、Textが多いのはPerlの面目躍如でしょうか。テキスト処理は十八番ですからね。

ちなみに、200回以上使われている名前は、138個。
100回以上200回未満は、171個。
10回以上100回未満は、2109個。
5回以上10回未満は、1686個。
2回以上5回未満は、5803個。
1回だけは、21289個でした。

メールマガジンの「Perlで書く」を読んでいたら、なんとなく試してみたくなったので、実行してみた。
continue構文は使ったことない。
使いどころがわからないというか、意識したこともなかった。

参考

ついでに、普通だったらこう書くよね、という感じのforeachも入れてベンチマークをとってみた。

結果

                      Rate sub_while_continue         sub_for sub_foreach_normal
sub_while_continue 75245/s                 --             -1%                -9%
sub_for            76220/s                 1%              --                -8%
sub_foreach_normal 83126/s                10%              9%                 --

結果はforeachがやはり速い。
foreach以外はループするかどうかの判断をしている分、遅くなるのはしょうがないのだろう。

ベンチマークコードは以下のとおり。

相変わらず「モダンPerl入門」を読み進めている。
「2.3 Composite」まで進んだが、ここのサンプルソースが結構間違っていた。

カンマが抜けていたり、関数名が違っていたり。
そのあたりは簡単に予想できたのだけど、大変だったのは「Shape::Composite」に
「use MooseX::AttributeHelpers」がなかったために、わけのわからないエラーに悩まされたことだ。
気づいてみれば、この章の始めのほうにもMooseX::AttributeHelpersを多用するとは書いてあるのだが、以下のようなエラーからはとても思いつかなかった。

Could not load class (Moose::Meta::Attribute::Custom::Collection::Array) because : Can't locate Moose/Meta/Attribute/Custom/Collection/Array.pm in @INC (@INC contains: lib C:/strawberry/perl/lib C:/strawberry/perl/site/lib .) at C:/strawberry/perl/site/lib/Class/MOP.pm line 153.
 
Could not load class (Collection::Array) because : Can't locate Collection/Array.pm in @INC (@INC contains: lib C:/strawberry/perl/lib C:/strawberry/perl/site/lib .) at C:/strawberry/perl/site/lib/Class/MOP.pm line 153.
 at C:/strawberry/perl/site/lib/Class/MOP.pm line 135
    Class::MOP::load_first_existing_class('Moose::Meta::Attribute::Custom::Collection::Array', 'Collection::Array') called at C:/strawberry/perl/site/lib/Moose/Util.pm line 143
    Moose::Util::resolve_metaclass_alias('Attribute', 'Collection::Array') called at C:/strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 97
    Moose::Meta::Attribute::interpolate_class('Moose::Meta::Attribute', 'provides', 'HASH(0x1160f6c)', 'metaclass', 'Collection::Array', 'isa', 'ArrayRef', 'default', 'CODE(0x1041e44)', ...) called at C:/strawberry/perl/site/lib/Moose/Meta/Attribute.pm line 86
    Moose::Meta::Attribute::interpolate_class_and_new('Moose::Meta::Attribute', 'shapes', 'provides', 'HASH(0x1160f6c)', 'metaclass', 'Collection::Array', 'isa', 'ArrayRef', 'default', ...) called at C:/strawberry/perl/site/lib/Moose/Meta/Class.pm line 510
    Moose::Meta::Class::_process_new_attribute('Moose::Meta::Class=HASH(0x104fb9c)', 'shapes', 'provides', 'HASH(0x1160f6c)', 'metaclass', 'Collection::Array', 'isa', 'ArrayRef', 'default', ...) called at C:/strawberry/perl/site/lib/Moose/Meta/Class.pm line 503
    Moose::Meta::Class::_process_attribute('Moose::Meta::Class=HASH(0x104fb9c)', 'shapes', 'provides', 'HASH(0x1160f6c)', 'metaclass', 'Collection::Array', 'isa', 'ArrayRef', 'default', ...) called at C:/strawberry/perl/site/lib/Moose/Meta/Class.pm line 202
    Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x104fb9c)', 'shapes', 'provides', 'HASH(0x1160f6c)', 'metaclass', 'Collection::Array', 'isa', 'ArrayRef', 'default', ...) called at C:/strawberry/perl/site/lib/Moose.pm line 89
    Moose::has('Shape::Composite', 'shapes', 'metaclass', 'Collection::Array', 'is', 'rw', 'isa', 'ArrayRef', 'auto_deref', ...) called at C:/strawberry/perl/site/lib/Moose/Exporter.pm line 201
    Moose::Exporter::__ANON__('shapes', 'metaclass', 'Collection::Array', 'is', 'rw', 'isa', 'ArrayRef', 'auto_deref', 1, ...) called at lib/Shape/Composite.pm line 15
    require Shape/Composite.pm called at p051.pl line 8
    main::BEGIN() called at lib/Shape/Composite.pm line 0
    eval {...} called at lib/Shape/Composite.pm line 0
Compilation failed in require at p051.pl line 8.
BEGIN failed--compilation aborted at p051.pl line 8.

最終的なShape::Compositeのソースは以下のとおり。

どこで読んだか忘れましたが、Perlのコミュニティの中では中堅クラスが少ない、という話がありました。

私としては、CPANによる自由拡張性が、そもそも裾野を広げる障害ではなかったか、と思います。
これは、MENTAを使っていく中で色々と読んでの感想ですが、軽量フレームワークが誕生した背景にも同じことがあったと思います。

Perlでウェブアプリケーションを開発する時にCPANモジュールを多く使っていると、公開する時点でサーバーを選んでしまいます。
つまり、Perlを学んでいけばいくほど公開する場所に制限がかかっていきます。CPANが自由に使えるサーバーは自前で用意する必要があるでしょう。
例えばMooseを使ってスクリプトを作っても、公開できるレンタルサーバーとなると、サクラサーバーくらいしかないのではないでしょうか?
私は使ったことがないのでわかりませんが、ユーザー領域にインストールする方法があるようですし。

参考
otsune's FreeBSD memo :: ユーザー領域にCPANをインストールする方法

その問題を解決するには、Perlで作られたプログラムを公開するためのレンタルサーバーを用意する、というのが良いのではないでしょうか?
Bundle::JPAという構想もあるようですし、そのBundle::JPAがインストールされたサーバーを用意すればPerlの普及に寄与することができるのではないか、と思います。JPAというPerlの団体が発足しましたが、その動きに期待したいところですね。

「モダンPerl入門」相変わらずゆっくりと読んでます。
別名というか、英語表記で「PRAGMATIC Perl」と書いてあります。
Pragmaticというのは「実際的な」とか「実用的な」「実利的な」といった意味のようです。

で、ようやく第一章を読み終わりました。
近代的なオブジェクト指向ということで、主にMooseの紹介でした。

その中で、Moose::Roleが出てきましたが、この考え方が面白いです。
面白いというか、すっと腑に落ちたという感じです。
基本的考え方として、役割を定義するクラスを作って、それを継承することで別のクラスに意味づけをする、という風に理解しています。
Moose::Roleでは継承の仕組みが拡張されていて、指定したメソッドを必ず備えるように縛ることができます。

MovableTypeでも、最近はカテゴリーとタグがありますが、従来の継承はカテゴリー、Moose::Roleで拡張される「役割」はタグ、というイメージでしょうか。

CPAN:Moose::Role - The Moose Role

で、例としてキャッシュのアダプターが紹介されていましたが、CPANに同等の機能を持つMooseX::Role::WithCacheというモジュールがある、ということでしたが、名前が違っていました。
正しくはMooseX::WithCacheでした。
いきなりcpanコマンドでインストールしようとしたら、存在しないというエラーが返ってきてビックリしました。

CPAN:Daisuke Maki / MooseX-WithCache - search.cpan.org


ただ、問題なのは、この辺を勉強してもレンタルサーバーでは使えない、ということなんですね…。

Mooseをuseすると自動的にstrictになる、というのが不思議だったのだが、その解説が見つかった。

プラグマを import すると use したクラスにもプラグマが効くようになる

…ということです。

useすると、自動的にimport関数が実行されるわけですが、この機能を利用してstrictなどのプラグマもimportさせることができる、ということのようです。
ふと気づいてMENTAのソースも見ましたが、同じような仕組みになっていました。

なので、importをしないようにuseすると、当然プラグマもimportされません。

use Moose ();
$n = 999;
print $n;

↑だとエラーが出ません。

use Moose;
$n = 999;
print $n;

で、こうした場合は、以下のようなエラーが出ます。

Moose does not export its sugar to the 'main' package.
Global symbol "$n" requires explicit package name at D:\WebApp\copal\copal.tmp line 2.
Global symbol "$n" requires explicit package name at D:\WebApp\copal\copal.tmp line 3.
Execution of D:\WebApp\copal\copal.tmp aborted due to compilation errors.

Mooseからのメッセージは謎ですね。
sugarってどういう意味なんでしょう?


ちなみに、この手のちょっとしたコードは、Copal 2を使って書いています。
エディタ機能はそれほどでもありませんが、保存しなくても一時ファイルを使って実行してくれるので、手軽で便利です。

…というようなエントリーをちらほら見かけた。
で、今日、Amazonからうちにも届いた。

モダンPerl入門 (CodeZine BOOKS)
牧 大輔
翔泳社
売り上げランキング: 210

Mooseが面白そうなので、最初からソースを自分で入力してみることにした。
自分で書くほうがソースを何度も見る(読む)事にもなるし、実際に動くところを見るのもよさそうだったから。

「use Moose」で自動的にstrictになる、というのが不思議。
とはいえ、「use strict」を書かないのも気持ち悪く、微妙な気持ちだが、慣れればそんなものかも。

ちなみに既に正誤表が用意されているようです。
『モダンPerl入門』正誤表

そういえば、一つ動かないソースがありました。

p14

sub write_response {
    my ($self, $client, $request) = @_;
    print $client scalar(localtime), " ";
    $self->SUPER($client, $request);
}

これを実行すると、クライアントからリクエストを打つとエラーで止まりました。

Can't locate object method "SUPER" via package "TimestampedEchoServer" at TimestampedEchoServer.pm line 11, <GEN1> line 1.

この間違いは単純なもので、正しくはSUPERの先に関数名が必要です。

sub write_response {
    my ($self, $client, $request) = @_;
    print $client scalar(localtime), " ";
    $self->SUPER::write_response($client, $request);
}

まあ、Mooseを使うのであれば、before等を使うほうが良いでしょうね。

Perlをツール的に使っていて、コードの中で複数の階層にあるファイルをディレクトリごと再帰的にコピーしたくなった。
以前、ファイルのコピーについて何か書いた気がして調べてみたのだが、大したことが書いていなかった…。

ファイルのコピーをする場合は、File::Copyというモジュールを使うのが良い。

ということで、他の方法を調べてみたところ、「File::Copy::Recursive」を使うのがよさそうだ、というところに行き着いた。
標準モジュールではないのでcpanからインストールする必要があったが、特に問題はなくスムーズにインストールできた。

現在のディレクトリ以下のファイルを、絶対パスの「/temp」へコピーする場合は、以下のようにする。

use strict;
use warnings;
use File::Copy::Recursive qw(rcopy);
 
my $from_dir = ".";
my $to_dir   = "/temp";
 
rcopy($from_dir, $to_dir);

参考:
Daniel Muey / File-Copy-Recursive - search.cpan.org

今までに加えて、下記の点でパワーアップした。

  • 最新の検索がいつ頃だったかも抽出できる。
  • 検索回数が指定回数以下のものについては無視できる。
  • クラウドにしやすいように検索回数をランク付けできる。

以上によって2回以上検索された語句のような物が生成できます。
今のスタイルシートでは、古い検索ほど色を暗い感じに、検索回数が多いほどフォントサイズを大きめに、ということにしています。
一部のブラウザでは意図したようには見えていないかもしれません(特に明暗について)が、Firefoxでは確認済みです。

検索された語句リストを見ていると、「まほでんわーるど」「攻略」で来てる人が多いようだ。
クラスチェンジの条件や強そうなクラスなどは、「まほでんわーるど Wiki*」が詳しいのでそちらに譲るとして、私が思うコツを一つだけ書いてみます。

そのコツとは「死なないこと」です。

当たり前と思われるでしょうが、まあ聞いて下さい。

まほでんわーるどでは、冒険中にキャラクターが死ぬと、そのときの冒険でキャラクターが得た経験値が0になってしまいます。
死なずに帰ってくる事を繰り返せば、それだけで効率よくレベルアップさせることができるというわけです。
強くなってくれば、敵を早く倒せる→お金が早く手に入る→仲間を早く増やせる、という良い循環になっていきます。

冒険に出発してしまうと、退却しか命令できないので、いかにタイミングよく退却するかが重要です。
特にクレリック等の回復スキルを持つキャラクターが居ない序盤に関しては、監視を怠ることは死を意味します。
放っておく事ができるゲームですが、放っておくといつまで経っても強くなれないことを覚えておきましょう。

最低レベルクラスチェンジに関しては、さほど気にすることはありません。
まずは回復キャラクターを作ることを意識すれば良いくらいです。
ちなみに巫女はあまり強くならない、かつ、それ以上クラスチェンジできないのでお奨めしません。あくまで好みで。

続きはネタバレがメインです。

Amazonで、「モダンPerl入門」を注文した。

Amazonから荷物が届くたびに、妻に「今度は何買ったの」と言われるのですが、妻はよく通販を利用しているのでどっちもどっちだと思っています。
思いついたときに予約・購入できるというのは強みだと思います。
まあ、買うのを忘れているほうが財布には優しいのですが。

モダンPerl入門
モダンPerl入門
posted with amazlet at 09.02.03
牧 大輔
翔泳社
売り上げランキング: 132

面白い記事を読んだので、早速試してみた。

そこで使ってみたいのがBlackbirdだ。Google Code上で公開されているオープンソースのJavaScriptアラートだ。

JavaScriptでコーディングするときに、alertで中身を確認するのは基本中の基本。
jGrowlもalertの代替な感じでしたが、jGrowlはお知らせ的な使い方が似合っている。

それに対して、このBlackbirdはログの要素が強い。
ロギングユーティリティを名乗るだけはある。

色々と書こうかと思っていたが、すでに色々と書かれているのでサンプルを適当に作ってお茶を濁すことにした。

色々と書かれている記事:
プログラマだって生きている:Javascript Logging Utility Blackbirdを試してみる

オフィシャル:
Blackbird - Open Source JavaScript Logging Utility

まあ、流れ的に試してみようかと。

結果からすると、こちらもforeachの方が速いようだ。

今回のベンチマークはstrawberryperlでやった。
-Vした結果はこんな感じ。

Summary of my perl5 (revision 5 version 10 subversion 0) configuration:
  Platform:
    osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags =' -s -O2 -DWIN32 -DHAVE_DES_FCRYPT  -DPERL_IMPLICIT_CONTE
XT -DPERL_IMPLICIT_SYS -fno-strict-aliasing -DPERL_MSVCRT_READFIX',
    optimize='-s -O2',
    cppflags='-DWIN32'
    ccversion='', gccversion='3.4.5', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long', lseek
size=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\li
b"'
    libpth=C:\strawberry\c\lib
    libs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm
 -lversion -lodbc32 -lodbccp32
    perllibs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdl
g32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lw
inmm -lversion -lodbc32 -lodbccp32
    libc=-lmsvcrt, so=dll, useshrplib=true, libperl=libperl510.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\st
rawberry\c\lib"'


Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP PL_OP_SLAB_ALLOC USE_ITHREADS
USE_LARGE_FILES USE_PERLIO
Built under MSWin32
Compiled at Oct 19 2008 15:47:04
@INC:
C:/strawberry/perl/lib
C:/strawberry/perl/site/lib
.


あまり意識したことが無かった。

いや、Perlの人も特段理由が無ければwhile(my($key, $value) = each %hash)を使用する。

Perlの人を自称しているけど、foreachでループしてたなぁ。
実は、勝手にそう思っているだけでPerlの人ではないのかも?(ぉ

気になったのでベンチマークをとってみたら、foreachが速かった。
もしかして、以前もやったことあるのかも。
それでeachをあまり使わない、とか。
いや、記憶に無いけど。

ついでに、forとforeachで何か違うかと思ってやってみたが、そうでもなかった。

ちなみに、eachに関しては以下のような記事もある。

each関数のメモリ消費量は、ごくわずか。keys関数のように、キーのすべてをメモリに読み込まない。

メモリを節約するのに、速度を犠牲にしているのかも?
今回は、小さなハッシュしか試していないが、大きなハッシュだと結果が違うのかも?

開発(実験)スクリプト用にバーチャルホストを作ったので、以前作っていたサンプルをそちらに移した。

その際、メニューが味気ないと思い、jQueryを使って階層メニューを作った。
試行錯誤はあったものの、結果的にはシンプルに実装できた。と思う。

参考にしたサイト

Google検索

Last.fm

このアーカイブについて

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

前のアーカイブは2009年1月です。

次のアーカイブは2009年3月です。

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

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