# rtoa-pgatram-mce.pl # Example run: perl rtoa-pgatram-mce.pl t1.txt >mce.tmp # # Convert a "modern" Roman Numeral to its arabic (decimal) equivalent. # The alpabetic input string may be assumed to always contain a valid Roman Numeral in the range 1-3999. # Roman numerals may be upper or lower case. # Error handling is not required. # For example: # input "XLII" should produce the arabic (decimal) value 42 # input "mi" should produce the arabic (decimal) value 1001 use strict; use warnings; use List::Util qw(reduce); use Time::HiRes qw(time); use MCE; # Function roman_to_arabic # Output a list of their arabic (decimal) values to standard output. # sub roman_to_arabic { my $files = shift; # in: reference to a list of files containing Roman Numerals (one per line) my %rtoa = ( M=>1000, D=>500, C=>100, L=>50, X=>10, V=>5, I=>1 ); # construct a pool of workers my $mce = MCE->new( max_workers => MCE::Util::get_ncpu(), chunk_size => 90 * 1024, init_relay => 1, # if defined, tells MCE to load MCE::Relay plus extra setup posix_exit => 1, user_func => sub { my ( $mce, $chunk_ref, $chunk_id, $output ) = ( @_, '' ); chomp @{$chunk_ref}; for ( @{$chunk_ref} ) { # $output .= reduce { $a+$b-$a%$b*2 } map { $rtoa{$_} } split //, uc($_); $output .= reduce { $a+$b-$a%$b*2 } @rtoa{ split //, uc($_) }; $output .= "\n"; } # output orderly MCE::relay { print $output }; } ); # process a list of files for my $fname ( @{$files} ) { warn("$0: cannot access '$fname': No such file or directory\n"), next unless -e $fname; warn("$0: cannot access '$fname': Permission denied\n"), next unless -r $fname; warn("$0: cannot process '$fname': Is a directory\n"), next if -d $fname; $mce->process({ input_data => $fname }); } # reap MCE workers $mce->shutdown; } @ARGV or die "usage: $0 file...\n"; my @rtoa_files = @ARGV; warn "rtoa pgatram start\n"; my $tstart = time; roman_to_arabic(\@rtoa_files); warn sprintf("time %0.03f secs\n", time - $tstart); #### $ time ./rtoa-pgatram t1.txt >cpp.tmp read_input_file : 3999000 items read file time : 0.136 secs roman_to_dec time : 0.116 secs output time : 0.187 secs real 0m0.450s user 0m0.416s sys 0m0.034s $ time perl rtoa-pgatram.pl t1.txt >pgatram.tmp rtoa pgatram start read_input_files : 1 secs roman_to_arabic : 4 secs output : 1 secs total : 6 secs real 0m6.259s user 0m6.131s sys 0m0.128s $ time perl rtoa-pgatram-mce.pl t1.txt >mce.tmp rtoa pgatram start time 1 thread : 5.808 secs time 8 threads : 1.151 secs ( 5.05x) time 16 threads : 0.643 secs ( 9.03x) time 32 threads : 0.347 secs (16.74x) time 64 threads : 0.225 secs (25.81x) 1 thd 8 thds 16 thds 32 thds 64 thds real 0m5.835s 0m1.178s 0m0.671s 0m0.375s 0m0.252s user 0m5.832s 0m9.064s 0m8.874s 0m8.935s 0m9.698s sys 0m0.008s 0m0.024s 0m0.030s 0m0.073s 0m0.136s #### $ cksum cpp.tmp pgatram.tmp mce.tmp 1397892467 18888000 cpp.tmp 1397892467 18888000 pgatram.tmp 1397892467 18888000 mce.tmp