2013-05-28 9 views
2

我要转换的逗号分隔列表ABCDEFA,B,C,D,E,F的Perl:长字符串转换为字节

什么是做到这一点的最快方式使用Perl的

我有很多字符串可以转换,字符串可以长达32768字节。所以,我想降低字符串转换的开销。

回答

8

如何

$string =~ s/.\K(?=.)/,/g;  # using \K keep escape 
$string =~ s/(?<=.)(?=.)/,/g; # pure lookaround assertion 

或者

$string = join ",", split(//, $string); 

要找到最快的解决方案,使用Benchmark

附加题:

这是一个基准我尝试的结果。令人惊讶的是,\K转义比纯粹的lookaround快得多,这与split/join差不多。

use strict; 
use warnings; 
use Benchmark qw(cmpthese); 

my $string = "ABCDEF" x 1000; 

cmpthese(-1, { 
    keep  => 'my $s = $string; $s =~ s/.\K(?=.)/,/g', 
    lookaround => 'my $s = $string; $s =~ s/(?<=.)(?=.)/,/g', 
    splitjoin => 'my $s = $string; $s = join ",", split(//, $string)' 
}); 

输出:

    Rate splitjoin lookaround  keep 
splitjoin 6546367/s   --  -6%  -47% 
lookaround 6985568/s   7%   --  -44% 
keep  12392841/s  89%  77%   -- 
+0

似乎总是同时提交......很好的答案。 – Lucas

+0

@Lucas谢谢。是的,有时竞争很激烈。 – TLP

+0

'unpack'(a)*''比'split'更快,但不足以超过“keep”。 – ikegami

1
my $str = "ABCDEFGHIJKL"; 

my @chars = $str =~ /./sg; 

print join ",", @chars; 
2
$ perl -le 'print join(",", unpack("(A)*", "hello"))' 
h,e,l,l,o 

$ perl -le 'print join(",", unpack("C*", "hello"))' 
104,101,108,108,111 

$ perl -le 'print join(",", unpack("(H2)*", "hello"))' 
68,65,6c,6c,6f 
+0

我喜欢这些。我在'unpack'函数中想过但不习惯它。而且看起来很快。 ** + 1 ** – Birei

+0

@Birei,'(A)*'的版本比我保留的'cmpthese'少了一半。我仍然想知道broncofan7是否真的想要这些字母,因为他说'字节'。 –

1

如果你想以较低的开销打印字符串,您可能希望只打印字符串,而你解析它,而比做内存中的整个转换,即

while (m/(.)\B/gc){ 
print "$1,"; 
}; 
if (m/\G(.)/) { 
    print "$1\n"; 
} 
+0

'\ B'很聪明,但只有在字符串中不出现标点符号和其他文字边界字符。 – TLP

+0

是的,如果字符串不像问题那么简单,他们可能需要延迟打印每个字母,直到看到下一个字母为止,这样他们就可以将最后一个字母打印出来并打印出来。尽管如此,m /(。)/ g方法仍然可以适应。 –