Perl:切片数组,而不创建一个全新的数组

时间:2013-03-01 15:10:54

标签: performance perl slice

我有一个大数组的引用,并且需要使用一些元素(从某个索引到结尾)在数据库中插入新行。

无论如何我可以创建一个更大数组的部分引用吗? 或者另一种方法,我可以使用DBI的execute_array函数的数组的一部分,而不在后台复制Perl数据?

这是我想要更有效率地做的事情:

$sh->execute_array({}, [ @{$arrayref}[@indexes] ]);

3 个答案:

答案 0 :(得分:5)

数组切片返回多个值并具有@ sigil:

my @array = (1, 2, 3, 4);

print join " ", @array[1..2]; # "2 3"

my $aref = [1, 2, 3, 4];

print join " ", @{$aref}[1..3]; # "2 3 4"

切片将返回标量列表(!=数组)。但是,这本身并不是副本:

my @array = (1, 2, 3, 4);

for (@array[1..2]) {
  s/\d/_/; # change the element of the array slice
}

print "@array"; # "1 _ _ 4"

所以这非常有效。

如果要创建新数组(或数组引用),则必须复制值:

my @array = (1, 2, 3, 4);

my @slice = @array[1..2];

my $slice = [ @array[1..2] ];

语法\@array[1..2]将返回切片中每个元素的引用列表,但不会返回切片的引用列表。

答案 1 :(得分:4)

$sh->execute_array({}, [ @{$arrayref}[@indexes] ]);

类似于

sub new_array { my @a = @_; \@a }
$sh->execute_array({}, new_array( @{$arrayref}[@indexes] ));

请注意复制切片所有元素的赋值。我们可以避免复制标量,如下所示:

sub array_of_aliases { \@_ }
$sh->execute_array({}, array_of_aliases( @{$arrayref}[@indexes] ));

现在,我们只是复制指针(SV*)而不是整个标量(以及其中的任何字符串)。

答案 2 :(得分:1)

Perl中的参数传递以“按引用传递”开头。如果您想知道是否进行了值复制,请查看源代码。

在这种情况下,execute_array第二行的定义会将@_引用的值复制到名为@array_of_arrays的词汇中。

从好的方面来看,这是一个浅薄的副本。 (至少就我看来而言。)