使用Perl字符串表现

jus*_*tkt 10 string perl performance concatenation string-concatenation

我一直在运行很多Perl代码,以这种方式打破长串:

my $string = "Hi, I am a very long and chatty string that just won't";
$string .= " quit.  I'm going to keep going, and going, and going,";
$string .= " kind of like the Energizer bunny.  What are you going to";
$string .= " do about it?";
Run Code Online (Sandbox Code Playgroud)

从我的Java背景来看,构建一个像这样的字符串将是一个禁忌的表现.Perl也是如此吗?在我的搜索中,我已经读过join在字符串数组上使用是连接字符串的最快方法,但是当你想要分解字符串以提高可读性时呢?写作更好:

my $string = "Hi, I am a very long and chatty string that just won't" .
    " quit.  I'm going to keep going, and going, and going," .
    " kind of like the Energizer bunny.  What are you going to" .
    " do about it?";
Run Code Online (Sandbox Code Playgroud)

或者我是否使用join,或者应该如何使用?

Jus*_* R. 15

骆驼书,第598页:

首选连接("",...)到一系列连接的字符串.多个连接可能导致字符串多次来回复制.连接运算符可以避免这种情况.

  • 这可能是写的时间.它不是perl 5.18.`perl -Mstrict -MBenchmark -we'timethis -10,sub {my $ output =""; foreach(1 .. 10000){$ output.= chr(rand(127))x1234; 在我的机器上``返回`11 wallclock secs(10.71 usr + 0.00 sys = 10.71 CPU)@ 491.13/s(n = 5260)``perl -Mstrict -MBenchmark -we'timethis -10,sub {my @块; foreach(1 .. 10000){push @chunks,chr(rand(127))x1234; } my $ output = join("",@ chunks); ''返回11个挂钟秒(10.56 usr + 0.00 sys = 10.56 CPU)@ 134.09/s(n = 1416).这是3的因素.= beats push + join. (2认同)

Eth*_*her 11

还有一件事要添加到这个尚未提及的线程 - 如果可以,请避免加入/连接这些字符串.许多方法将字符串列表作为参数,而不仅仅是一个字符串,因此您可以单独传递它们,例如:

print "this is",
    " perfectly legal",
    " because print will happily",
    " take a list and send all the",
    " strings to the output stream\n";

die "this is also",
    " perfectly acceptable";

use Log::Log4perl :easy; use Data::Dumper;
INFO("and this is just fine",
    " as well");

INFO(sub {
    local $Data::Dumper::Maxdepth = 1;
    "also note that many libraries will",
    " accept subrefs, in which you",
    " can perform operations which",
    " return a list of strings...",
    Dumper($obj);
 });
Run Code Online (Sandbox Code Playgroud)


seb*_*ert 10

我做了基准!:)

#!/usr/bin/perl

use warnings;
use strict;

use Benchmark qw(cmpthese timethese);

my $bench = timethese($ARGV[1], {

  multi_concat => sub {
    my $string = "Hi, I am a very long and chatty string that just won't";
    $string .= " quit.  I'm going to keep going, and going, and going,";
    $string .= " kind of like the Energizer bunny.  What are you going to";
    $string .= " do about it?";
  },

  one_concat => sub {
    my $string = "Hi, I am a very long and chatty string that just won't" .
    " quit.  I'm going to keep going, and going, and going," .
    " kind of like the Energizer bunny.  What are you going to" .
    " do about it?";
  },

  join => sub {
    my $string = join("", "Hi, I am a very long and chatty string that just won't",
    " quit.  I'm going to keep going, and going, and going,",
    " kind of like the Energizer bunny.  What are you going to",
    " do about it?"
    );
  },

} );

cmpthese $bench;

1;
Run Code Online (Sandbox Code Playgroud)

结果(在我的iMac上使用Perl 5.8.9):

imac:Benchmarks seb$ ./strings.pl 1000
Benchmark: running join, multi_concat, one_concat for at least 3 CPU seconds...
      join:  2 wallclock secs ( 3.13 usr +  0.01 sys =  3.14 CPU) @ 3235869.43/s (n=10160630)
multi_concat:  3 wallclock secs ( 3.20 usr + -0.01 sys =  3.19 CPU) @ 3094491.85/s (n=9871429)
one_concat:  2 wallclock secs ( 3.43 usr +  0.01 sys =  3.44 CPU) @ 12602343.60/s (n=43352062)
                   Rate multi_concat         join   one_concat
multi_concat  3094492/s           --          -4%         -75%
join          3235869/s           5%           --         -74%
one_concat   12602344/s         307%         289%           --
Run Code Online (Sandbox Code Playgroud)

  • `one_concat`由编译器优化为在运行时具有0个连接的常量赋值. (7认同)