package TGrep;
use strict;
use threads;
use Thread::Queue;
our $WORKERS = 4;
sub g_proxy {
my( $code, $Qin, $Qout ) = @_;
$Qout->enqueue( $code->() ? $_ : () ) while local $_ = $Qin->dequeue;
$Qout->enqueue( undef );
}
sub tgrep(&@) {
my $workers = $WORKERS;
my $code = shift;
my( $Qin, $Qout ) = map Thread::Queue->new, 1..2;
async( \&g_proxy, $code, $Qin, $Qout )->detach for 1 .. $workers;
$Qin->enqueue( map{ ref $_[0] ? @{ $_ } : $_ } @_ );
$Qin->enqueue( (undef) x $workers );
my @results;
push @results, $_ while $_ = $Qout->dequeue;
return wantarray ? @results : \@results;
}
sub import {
no strict 'refs';
my $pkg = caller;
*{ $pkg . '::' . $_ } = *{ $_ } for qw[ tgrep ];
}
1;
####
#! perl -slw
use strict;
use TGrep;
use Time::HiRes qw[ time ];
our $N //= 1e3;
my $start = time;
my @a = tgrep{ $_ % 5 == 0 } [ 1..$N ];
printf "Took %.9f seconds\n", time() -$start;
print scalar @a;
__END__
C:\test>t-tgrep -N=1e5
Took 3.830074787 seconds
20000
####
$t=time;
my @a = grep{ $_%5 == 0 } 1 .. 1e6;
print time-$t;;
0.18144702911377