#!perl -l use 5.012; # strict, // use warnings; use open ':std', ':encoding(UTF-8)'; use Data::Dump; sub mem { `tasklist /nh /fi "PID eq $$"`=~ m[(\S+ K)$] } # [id://1175244] # grabs memory usage on Windows systems; if you have Memory::Usage, some of it's functions will work as well # store the characters for certain posix character classes for U+0000 thru my $class = "alpha"; my $max_codepoint = 0xEFFFF; sub store_using_arrays { my @store; for my $c ( 0 .. $max_codepoint ) { my $character = chr($c); push @store, $character if $character =~ /[[:${class}:]]/; } return \@store; } sub store_using_strings { my $store; for my $c ( 0 .. $max_codepoint ) { my $character = chr($c); $store .= $character if $character =~ /[[:${class}:]]/; } return $store; } sub build_inversion_list_and_index { my @invlist; my $match; for (0..$max_codepoint) { next unless $match xor (chr($_) =~ /[[:$class:]]/); push @invlist, $_; $match= !$match; } my @index= ( 0 ); for (my $i= 0; $i < @invlist; $i+= 2) { push @index, $index[-1] + $invlist[$i+1] - $invlist[$i]; } shift @index; return \@invlist, \@index; } sub get_nth_char { my ($i, $invlist, $index) = @_; return undef if $i >= $index->[-1]; my ($min, $max, $mid)= (0, $#$index); while (1) { $mid= ($min+$max) >> 1; if ($i > $index->[$mid]) { $min= $mid+1 } elsif ($mid > 0 && $i < $index->[$mid-1]) { $max= $mid-1 } else { return $invlist->[$mid*2] + ($i - ($mid > 0? $index->[$mid-1] : 0)) } } } # memory comparisons: { print "mem before generate arrays: ", mem(); my $ref = store_using_arrays(); print "mem after generate arrays: ", mem(); undef $ref; print "mem after delete arrays: ", mem(); } { print "mem before generate strings: ", mem(); my $str = store_using_strings(); print "mem after generate strings: ", mem(); undef $str; print "mem after delete strings: ", mem(); } { print "mem before generate inversions: ", mem(); my @refs = build_inversion_list_and_index(); print "mem after generate inversions: ", mem(); undef @refs; print "mem after delete inversions: ", mem(); } require Benchmark; my ($aref, $strn, $ilist, $iidx); print "COMPARE GENERATING:"; Benchmark::cmpthese(-10, { 'genArr' => sub { $aref = store_using_arrays }, 'genStr' => sub { $strn = store_using_strings }, 'genInv' => sub { ($ilist, $iidx) = build_inversion_list_and_index }, }); # dd $aref; dd $strn; #($ilist, $iidx) = build_inversion_list_and_index(); #dd $ilist; dd $iidx; #print $_, " => ", get_nth_char($_, $ilist, $iidx) for 0 .. 32; my $aasize = scalar @$aref; my $sasize = length $strn; my $iasize = scalar @$ilist; my (@arec, @srec, @irec); use constant MAX_REC => (10_000 - 1); $#arec = $#srec = MAX_REC; print "COMPARE ACCESSING:"; Benchmark::cmpthese(-10, { 'getArr10k' => sub { $arec[$_] = $aref->[rand $aasize] for 0 .. MAX_REC }, 'getStr10k' => sub { $srec[$_] = substr($strn, rand($sasize), 1) for 0 .. MAX_REC }, 'getInv10k' => sub { $irec[$_] = get_nth_char(int rand($iasize), $ilist, $iidx) for 0 .. MAX_REC }, }); __END__ C:\Users\peter.jones\Downloads\TempData\perl>posix_bench.pl mem before generate arrays: 12,244 K mem after generate arrays: 26,460 K mem after delete arrays: 18,132 K mem before generate strings: 18,136 K mem after generate strings: 19,952 K mem after delete strings: 19,952 K mem before generate inversions: 19,952 K mem after generate inversions: 19,952 K mem after delete inversions: 19,956 K COMPARE GENERATING: Rate genArr genStr genInv genArr 1.32/s -- -7% -19% genStr 1.42/s 7% -- -13% genInv 1.62/s 23% 14% -- COMPARE ACCESSING: Rate getStr10k getInv10k getArr10k getStr10k 2.82/s -- -96% -99% getInv10k 69.7/s 2374% -- -83% getArr10k 422/s 14868% 505% --