我有这么长的音译:
$text =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑʙƀɓƃćĉčċçȼƈɕʗďđðɖɗƌȡéèĕêěëėȩęēȅȇɇɛ/aaaaaaaaaaaaaaaaabbbbcccccccccdddddddeeeee/;
# Etc. (About 400 chars)
我想将其分成几个音译,因为生成的代码更容易维护:
$text =~ tr/áàăâǎåǻäǟãȧǡąāȁȃɑ/aaaaaaaaaaaaaaaaa/;
$text =~ tr/ʙƀɓƃ/bbbb/;
$text =~ tr/ćĉčċçȼƈɕʗ/ccccccccc/;
# Etc.
我相信这会让事情变得缓慢,但我想肯定地知道。这个过程在非常繁忙的服务器上每秒运行大约1000次。
感谢。
答案 0 :(得分: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。
答案 1 :(得分:4)
我希望第二个解决方案有三个操作速度较慢,因为它会重新扫描$text
中已被替换的字符。
答案 2 :(得分: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倍。