in reply to Re^3: Risque Romantic Rosetta Roman Race - Tried Array Lookup
in thread Risque Romantic Rosetta Roman Race
The Perl MCE code can be made faster by applying CPU affinity and enabling slurp IO.
Updated on May 12, 2023 with tip from tybalt89 using unpack.
Updated on May 13, 2023: fixed typo.
# 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 containin +g Roman Numerals (one per line) my $apply_cpu_affinity = ( $^O =~ /linux/i ) ? 1 : 0; # ARRAY, characters M D C L X V I my @rtoa; @rtoa[qw( 77 68 67 76 88 86 73 )] = qw( 1000 500 100 50 1 +0 5 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 p +lus extra setup posix_exit => 1, use_slurpio => 1, user_begin => sub { if ( $apply_cpu_affinity ) { my $cpu = (MCE->wid - 1) % MCE::Util::get_ncpu(); system("taskset -cp $cpu $$ >/dev/null"); $apply_cpu_affinity = 0; } }, user_func => sub { my ( $mce, $slurp_ref, $chunk_id, $output ) = ( @_, '' ); open my $fh, '<', $slurp_ref; while ( <$fh> ) { chomp; $output .= reduce { $a+$b-$a%$b*2 } @rtoa[ unpack 'c*', uc +($_) ]; $output .= "\n"; } close $fh; # 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);
The UNIX real time includes ~ 0.06 seconds for launching Perl, loading modules, spawning and reaping workers.
# captured UNIX time C++ 1.0 : 0.450s C++ fast_io : 0.291s Perl MCE 64 thds : 0.252s # after tweaks: CPU affinity and slurp IO Perl MCE 64 thds : 0.218s # more tweaks: using an ARRAY and unpack Perl MCE 64 thds : 0.192s $ time perl rtoa-pgatram-mce.pl t1.txt >mce.tmp rtoa pgatram start time 0.165 secs real 0m0.192s user 0m7.596s sys 0m0.420s
|
---|