[Moscow.pm] POE::Filter::Line
Ivan B. Serezhkin
ivan на serezhkin.com
Пн Мар 17 08:53:37 PDT 2008
Ruslan Zakirov wrote:
> 2008/3/17 Ivan B. Serezhkin <ivan на serezhkin.com>:
>
>> Привет.
>> Может кому и интересно ?
>> получил прирос в 25 раз на больших файлах.
>> Можете поругать стиль =)
>> На очереди сделать нормальный быстрый драйвер.
>> И кстати, это удобный темплейт для написания своих фильтров, например
>> POE::Filter::Log::Postfix =)
>> Использовать так:
>>
>> Wheel ...
>> Driver => POE::Driver::SysRW->new( BlockSize => 256*1024*1024) ,
>> Filter => POE::Filter::Regexp->new(qr/RecordSeparator/),
>> ....
>>
>>
>>
>> package POE::Filter::Regexp;
>> use strict;
>>
>> sub new {
>> my ($class,$re)=@_;
>> $re ||= qr/\n/;
>> die "Param in new must be a Regexp but this is a ".ref($re) unless ref
>> $re eq 'Regexp';
>> return bless [
>> '', # raw unparsed data
>> [], # ready queue
>> $re,
>> ], $class;
>>
> Почему не ref($class)||$class?
>
>
>> }
>>
>> sub get {
>> my ($self, $stream) = @_;
>> my @ret;
>> while($self->[0].=shift @$stream){
>>
> $self->[0] .= $_ foreach @$stream;
>
можно, но тогда мы будем дважды жрать память под каждый input chunk
В результате я остановился на
while(shift @$stream){
$self->[0].=$_;
размеры элементов в $stream по идее должны быть равны BlockSize в драйвере.
Но вообще все эти навороты с отдельно драйвером, отдельно фильтром - это круто, но на самом деле сейчас не используется.
Драйвер всегда возвращает один кусок в $input и его сразу же скармливают в фильтр.
> Возможно будет быстрее. Нужно подчищать поток? Если да, то стоит
> оставить как у вас.
>
> Можно еще study добавить, хотя это может и замедлить.
>
> Если говорить о больших файлах, то память будет кушаться в больших
> кол-вах, если разделителя в потоке нет, но тут видимо ничего не
> поделаешь.
>
Я ею жертвую =)
Скорость важнее.
>
>> my $p=0;
>> while($self->[0]=~/$self->[2]/g) {
>> next unless $-[0]; #begin of stream
>> push @ret, substr($self->[0], $p, $-[0]-$p);
>> $p=$-[0];
>> }
>> substr($self->[0], 0, $p)=undef;
>>
> substr($self->[0], 0, $p) = "";
>
>
>> }
>> return \@ret;
>> }
>> 1;
>>
--
Ivan B. Serezhkin
Подробная информация о списке рассылки Moscow-pm