#!./perl use strict; use Encode; use Benchmark qw(:all); my $Count = shift @ARGV; $Count ||= 16; my @sizes = @ARGV || (1, 4, 16); my %utf8_seed; for my $i (0x00..0xff){ my $c = chr($i); $utf8_seed{BMP} .= ($c =~ /^\p{IsPrint}/o) ? $c : " "; } utf8::upgrade($utf8_seed{BMP}); for my $i (0x00..0xff){ my $c = chr(0x10000+$i); $utf8_seed{HIGH} .= ($c =~ /^\p{IsPrint}/o) ? $c : " "; } utf8::upgrade($utf8_seed{HIGH}); my %S; for my $i (@sizes){ my $sz = 256 * $i; for my $cp (qw(BMP HIGH)){ $S{utf8}{$sz}{$cp} = $utf8_seed{$cp} x $i; $S{utf16}{$sz}{$cp} = encode('UTF-16BE', $S{utf8}{$sz}{$cp}); } } for my $i (@sizes){ my $sz = $i * 256; my $count = $Count * int(256/$i); for my $cp (qw(BMP HIGH)){ for my $op (qw(encode decode)){ my ($meth, $from, $to) = ($op eq 'encode') ? (\&encode, 'utf8', 'utf16') : (\&decode, 'utf16', 'utf8'); my $XS = sub { Encode::Unicode::set_transcoder("xs"); $meth->('UTF-16BE', $S{$from}{$sz}{$cp}) eq $S{$to}{$sz}{$cp} or die "$op,$from,$to,$sz,$cp"; }; my $modern = sub { Encode::Unicode::set_transcoder("modern"); $meth->('UTF-16BE', $S{$from}{$sz}{$cp}) eq $S{$to}{$sz}{$cp} or die "$op,$from,$to,$sz,$cp"; }; my $classic = sub { Encode::Unicode::set_transcoder("classic"); $meth->('UTF-16BE', $S{$from}{$sz}{$cp}) eq $S{$to}{$sz}{$cp} or die "$op,$from,$to,$sz,$cp"; }; print "---- $op length=$sz/range=$cp ----\n"; my $r = timethese($count, { "XS" => $XS, "Modern" => $modern, "Classic" => $classic, }, 'none', ); cmpthese($r); } } }