# 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