#!/usr/bin/env perl use strict; use warnings; use utf8; use Benchmark qw(:all); use File::Find; use PIR; my $Usage = "$0 some/path\n"; die $Usage unless @ARGV and -d $ARGV[0]; open( my $fh, ">", '/dev/null' ); cmpthese( 50, { 'File::Find' => \&try_find, 'find pipe' => \&try_pipe, 'find pipe iter' => \&try_pipe_iter, 'PIR' => \&try_pir, 'PIR fast' => \&try_pir_fast, 'perl readdir' => \&try_readdir, } ); sub try_find { find( { wanted => sub { print $fh $_ if ( -f $_ ); }, follow_fast => 1 }, $ARGV[0] ); } sub try_pipe { open( FIND, "find -L $ARGV[0] -type f |" ); while () { print $fh $_; } close FIND; } sub get_pipe_iter { open( my $FH, "-|", "find -L $ARGV[0] -type f" ); return ( sub { return ( <$FH> ); } ); } sub try_pipe_iter { my $next = get_pipe_iter(); while ( defined( my $file = $next->() ) ) { print $fh $file; } } sub try_pir { my $rule = PIR->new; my $next = $rule->iter( $ARGV[0] ); while ( defined( my $file = $next->() ) ) { print $fh $file; } } sub try_pir_fast { my $rule = PIR->new; my $next = $rule->iter_fast( $ARGV[0] ); while ( defined( my $file = $next->() ) ) { print $fh $file; } } sub try_readdir { my ( @dirs ) = @_ ? @_ : @ARGV; foreach my $dir ( @dirs ) { opendir DIR, $dir; my @entries = readdir DIR; closedir DIR; foreach my $entry ( @entries ) { next if ( $entry =~ m/^\.+$/ ); if ( -d "$dir/$entry" ) { try_readdir( "$dir/$entry" ); } else { print $fh "$dir/$entry"; } } } }