perl の配列とメモリー2006年12月22日 08時06分47秒

朝の頭の体操に。

面白いな、と思ったのは、上記リンク先の話題を手元で試していたときに、

@data = map { rand 10 } (1..1e7);
$sum += $_ for @data;

だとメモリーを喰いまくるのに、

$sum += rand 10 for 1..1e7;

だとほとんどメモリーを喰わないこと。後者も for配列を回すループなのに。この書き方に限っては、内部では配列を作らずに動作しているのだろうか?

試しに↓も試してみる。

@arr = 1..1e7;
$sum += rand 10 for @arr;

これを、Win32 ActivePerl の環境で、タスクマネージャを起動しつつ、perl コマンドを呼び出してコンソール上で直打ちしていたわけですが (つまり、状況としては↓みたいな感じ)、

C:\Documents and Settings\murachi>perl
@arr = 1..1e7;
$sum += rand 10 for @arr;
^Z

面白いのは、以下の行を書いて [Enter] を押した時点で、タスクマネージャが perl コマンドプロセスによる大量のメモリー領域確保を検知したこと。

@arr = 1..1e7;

つまり、配列変数はコンパイル時に領域確保が行われる模様 (もちろん、変数の内容がコンパイル時に判別できる場合だけなんだろうけど)。結果として、最適化の余地がなくなってしまうわけか。

ループ文を含むスクリプトで異様にメモリーを喰いまくるのが気になる場合のチェックポイントとして認識しておくといいかも。ていうか、for ループで回す配列に直接範囲演算子による式を渡すとメモリーを喰わないってのは予想外だった。

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※投稿には管理者が設定した質問に答える必要があります。

名前:
メールアドレス:
URL:
次の質問に答えてください:
おいらがやっている会社の名前をひらがな4文字で。

コメント:

トラックバック

※トラックバックの受付件数を超えているため、この記事にトラックバックを投稿することができません。