Yappo::タワシ このページをアンテナに追加 RSSフィード

2008-05-13

tieしてSTDOUTにフックかける

HTTP::Engine の STDIN STDOUT 処理を Interface に read write API を生やして、Interfaceの外からwrite readを読んで処理するのか。

もしくは Interface は STDIN STDOUT をセットアップだけして Interface の外は print STDOUT $buffer とするだけでsocketに書き込めるようにするかの話がでました。


STDIN STDOUT だけセットアップするのは、Interface とそれ以外の依存度が減るので良いのですが、 Danga::Socket や POE などの非同期系IOを使う場合は、普通だと非同期な出力処理(write)が出来ないと思われます。というのはソース読んだら嘘でした><

でも write method 使わないと大変な事になりそうな気がする。教えて偉い人。


その悩みは tie で出来るよ。という事で IO::Scalar と tie を使って、 STDOUT に print したら任意のコードリファレンスに出力内容を渡す仕組みを作ってみました。

これで Danga::Socket とかで $sock->write して出力とか POE 等の任意のメソッドで出力出来ます。


で、ベンチ取ったら素のSTDOUTより倍遅い感じ。

tied  : 0 wallclock secs ( 0.60 usr +  0.00 sys =  0.60 CPU) @ 166666.67/s (n=100000)
scalar: 1 wallclock secs ( 0.32 usr +  0.01 sys =  0.33 CPU) @ 303030.30/s (n=100000)
normal: 0 wallclock secs ( 0.32 usr +  0.00 sys =  0.32 CPU) @ 312500.00/s (n=100000)
package Tied;
use strict;
use warnings;
use base 'IO::Scalar';

sub open {
    my ($self, $ref) = @_;

    ### Sanity:                                                                                                                    
    (ref($ref) eq "CODE") or Carp::croak "open() needs a ref to a code";

    ### Setup:                                                                                                                     
    *$self->{Pos} = 0;          ### seek position                                                                                  
    *$self->{CR}  = $ref;      ### code reference                                                                                  
    $self;
}

sub print {
    my $self = shift;
    *$self->{CR}->(@_);
    1;
}

package main;
use strict;
use warnings;
use Benchmark qw/timethese timeit timestr/;
use IO::Scalar;

my $count = 100_000;

my $tied = Tied->new( sub { print @_ } );
my $scalar = IO::Scalar->new( \my $buffer );

tie *STDOUT, 'IO::Scalar', \my $out;
my $t_tied = timeit $count => sub {
    print $tied "hoge\n";
};
my $t_scalar = timeit $count => sub {
    print $scalar "hoge\n";
};
my $t_normal = timeit $count => sub {
    print "hoge\n";
};
untie *STDOUT;

print "tied  :", timestr($t_tied), "\n";
print "scalar:", timestr($t_scalar), "\n";
print "normal:", timestr($t_normal), "\n";

DASMDASM 2008/05/28 23:08 Sanity とかいうダサいコメントはひろみちゅ先生的にヤヴァいんじゃないの?
消したら問題があるの? 死んだりはしないでしょ?

maypeecos@yaoo.commaypeecos@yaoo.com 2017/03/28 02:53 Dear Sir / Madam,
I wish to write you these letter asking for your concern.
We are group of local miners from Wasa Amefie area in the central region part of Ghana.
Has in stock 250 kg AU gold dust that seeking for interested buyer.
Please note , the price is negotiable.
Thanks.
Emmanuel

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yappo/20080513/1210615145