2

我是从 构建%grouped%uniq_c,其中%grouped包含通过拆分%uniq_c的 key IF%uniq_c的值足够高生成的键/值对。它相当有效,但我想做得更好。

%uniq_c = (
    'foo:baz'   => 3,
    'foo:quux'  => 12,
    'bar:corge' => 15,
    'bar:fred'  => 8,
);

foreach my $gv (keys %uniq_c) {
        if( $uniq_c{$gv} >= 10 ) {
                my ($g, $v) = split /:/, $gv, 2;
                push( @{$grouped{$g}}, $v );
        }
}

认为每次循环迭代都会发生三个字符串副本;1 代表 $g,2 代表 $v。有没有办法消除一个 $v 副本,或者更好的是,一个 $v 和一个 $g 副本(可能是某种字符串切片)?

作为参考,Data::Dump::dump(%grouped) 产生以下内容:

(
  "bar", ["corge"],
  "foo", ["quux"],
)
4

1 回答 1

4

对返回的值进行复制split非常有效;字符串缓冲区被盗而不是被复制。但是当你 push 时还有另一个副本完成$v。所有这三个副本都可以通过混叠来避免。

use Data::Alias qw( alias );

foreach my $gv (keys %uniq_c) {
        if( $uniq_c{$gv} >= 10 ) {
                alias my ($g, $v) = split /:/, $gv, 2;
                alias push @{$grouped{$g}}, $v;
        }
}
于 2012-06-13T19:32:28.190 回答