unpack
будет более эффективным, чем split
и ord
, потому что он не должен создавать кучу временных 1-символьных строк:
use utf8;
my $str = '中國c'; # Chinese language of china
my @codepoints = unpack 'U*', $str;
print join(',', @codepoints) . "\n"; # prints 20013,22283,99
Быстрый тест показывает, что он примерно в 3 раза быстрее, чем split+ord
:
use utf8;
use Benchmark 'cmpthese';
my $str = '中國中國中國中國中國中國中國中國中國中國中國中國中國中國c';
cmpthese(0, {
'unpack' => sub { my @codepoints = unpack 'U*', $str; },
'split-map' => sub { my @codepoints = map { ord } split //, $str },
'split-for' => sub { my @cp; for my $c (split(//, $str)) { push @cp, ord($c) } },
'split-for2' => sub { my $cp; for my $c (split(//, $str)) { $cp = ord($c) } },
});
Результаты:
Rate split-map split-for split-for2 unpack
split-map 85423/s -- -7% -32% -67%
split-for 91950/s 8% -- -27% -64%
split-for2 125550/s 47% 37% -- -51%
unpack 256941/s 201% 179% 105% --
Разница менее выражена с более короткой строкой, но unpack
все еще более чем в два раза быстрее. (split-for2
немного быстрее, чем другие разбиения, поскольку не создает список кодовых точек.)