2

我有这个很长的音译:

$text =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑʙƀɓƃćĉčċçȼƈɕʗďđðɖɗƌȡéèĕêěëėȩęēȅȇɇɛ/aaaaaaaaaaaaaaaaabbbbcccccccccdddddddeeeee/;
# Etc. (About 400 chars)

我想把它分成几个音译,因为生成的代码更容易维护:

$text =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑ/aaaaaaaaaaaaaaaaa/;
$text =~ tr/ʙƀɓƃ/bbbb/;
$text =~ tr/ćĉčċçȼƈɕʗ/ccccccccc/;
# Etc.

我相信这会减慢速度,但我想确定一下。这个过程在相当繁忙的服务器上每秒运行大约 1000 次。

谢谢。

4

3 回答 3

7

你可以建立一个音译:

my %translits = (
   'áàăâǎåǻäǟãȧǡąāȁȃɑ' => 'a',
   'ʙƀɓƃ'              => 'b',
   'ćĉčċçȼƈɕʗ'         => 'c',
);

my $pat  = '';
my $repl = '';
for (keys(%translit)) {
   $pat  .= $_;
   $repl .= $translit{$_} x length($_);
}

my $tr1 = eval "sub { tr/\Q$pat\E/\Q$repl\E/ }" or die $@;
   -or-
my $tr2 = eval "sub { \$_[0] =~ tr/\Q$pat\E/\Q$repl\E/ }" or die $@;

然后像这样使用它:

$tr1->() for $str;
   -or-
$tr2->($str);

当然,您总是可以使用Text::Unidecode

于 2013-11-06T02:12:46.017 回答
4

我希望具有三个操作的第二个解决方案会更慢,因为它会重新扫描$text已经被替换的字符。

于 2013-11-06T01:08:15.640 回答
2

这是一个基准:

use Benchmark qw(:all);

my $str = 'áàăâǎåǻäǟãȧǡąāȁȃɑʙƀɓƃćĉčċçȼƈɕʗďđðɖɗƌȡéèĕêěëėȩęēȅȇɇɛ/aaaaaaaaaaaaaaaaabbbbcccccccccdddddddeeeee';
my $count = -2;
cmpthese($count, {
    'one tr' => sub {
        $str =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑʙƀɓƃćĉčċçȼƈɕʗďđðɖɗƌȡéèĕêěëėȩęēȅȇɇɛ/aaaaaaaaaaaaaaaaabbbbcccccccccdddddddeeeee/;
    },
    'multi tr' => sub {
        $str =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑ/aaaaaaaaaaaaaaaaa/;
        $str =~ tr/ʙƀɓƃ/bbbb/;
        $str =~ tr/ćĉčċçȼƈɕʗ/ccccccccc/;
        $str =~ tr/ďđðɖɗƌȡ/ddddddd/;
        $str =~ tr/éèĕêěëėȩęēȅȇɇɛ/eeeee/;
    },
});

结果:

              Rate multi tr   one tr
multi tr 1215538/s       --     -81%
one tr   6271883/s     416%       --

正如我们所见,一个 tr 比 multi-tr 快 5 倍。

于 2013-11-06T09:28:54.560 回答