« やっていないこと (2) | メイン | 体調がやばいこそ自炊 »

2005年01月16日

alarm と time

繰り返し演算にタイムアウト処理を加えたいときがある。具体的には、クローラーが select で内容を受け取っているようなときかな。ずっと待ち続けるのもありだけど、まぁ。それなりの時間でタイムアウトするのが良い。

タイムアウトの方法には、純粋に alarm を使う方法と、スタート時間と今の時間を比べるような方法がある。現時点での実装では、なぜか後者を採用したのだが、ふと前者の実装の方がよいかも。と思った次第である。というか、実装時には、前者が思い浮かばなかった。それは eval と alarm をあまり使用しないからだと思う。まぁ。いいや。

単純なプログラムで、結果を比べてみた。

alarm.pl

#!/usr/bin/perl

use strict;
my $i;

eval {
    $SIG{'ALRM'} = sub {
        last;
    };
    alarm 5;

    while (1) {
        $i++;
    }

    alarm 0;
};

print $i . "\n";

exit;

timer.pl

#!/usr/bin/perl

use strict;
my ($start, $i);

$start = time;

while (5 >= time - $start) {
    $i++;
}

print $i . "\n";

exit;

time の結果だけでは面白くないので、ループを何回まわったかも数えることにした。タイムアウトは 5秒 とした。5秒という数字には特に意味が無いので、念のため。

$ time ./alarm.pl
24943828

real    0m5.007s
user    0m4.450s
sys     0m0.030s

$ time ./timer.pl
3444813

real    0m5.044s
user    0m3.270s
sys     0m1.630s

結果はこんな感じ。数回試したけど、似たような結果になるので。ループの回数が1桁違うという結果になりました。実行時間は、タイムアウトを 5秒 にしているので似たようなもの。内訳は全然違いますけど。

2005年01月16日 17:31 | Programming

トラックバック

コメント

ループの実行回数がループの条件式に極めて大きな影響を受けるのは、ループの内容処理が非常に高速なため、条件式の演算コストが大きく見えるためだと思われます。selectのようにブロックする関数を呼ぶ場合は、ループの条件式の軽さというのはそんなに関係ないのでは?たとえば$i++の前にusleep(1000)とか入れてみたら?

投稿者 sugi : 2005年01月17日 23:17

>> sugi さん
書きながらそう思ったので、エントリーには、評論を書きませんでした。
で、実際に usleep で試したら面白くない結果が出ました。どっちもあまり変わらないってことね。

投稿者 ceekz : 2005年01月19日 03:06