我的代码中有一节我知道我需要一个数组,而且我确切知道该数组需要多少个元素。这部分代码将重复很多,所以我可以节省一些非常大的时间,首先将该数组初始化为我知道它需要的大小,然后填充它而不仅仅推送项目(推送将是O( n)而不是填充已经创建的空间,这将是O(1))。
那就是说,我似乎无法找到将数组初始化为给定大小的任何优雅方式,我不知道为什么。我知道我能做到:
my @array; $array[49] =0;
得到一个50项阵列,但这看起来真的很丑我觉得好像一定有更好的方法。想法?
答案 0 :(得分:14)
说实话,你的方式非常好,就像明确改变数组的大小一样:$#array = 49;
;
答案 1 :(得分:12)
在你去之前测量,测量和测量,并假设你可以通过伪造Perl来更快地完成它。 Perl一直在进行常规使用的优化,比你拥有的时间长得多。相信它。
答案 2 :(得分:6)
每当您考虑进行此类优化时,请进行一些分析!结果可能不是您所期望的。例如,我使用以下快速脚本来测试您的理论,即预先分配数组的速度更快:
for ( my $loops = 0; $loops < 100000; $loops++ )
{
my @arr;
for ( my $foo = 0; $foo < 50; $foo++ ) {
push @arr, 'bar';
}
}
这需要2.13秒。
for ( my $loops = 0; $loops < 100000; $loops++ )
{
my @arr;
$arr[49] = 0;
for ( my $foo = 0; $foo < 50; $foo++ ) {
$arr[$foo] = 'bar';
}
}
花了2.16秒(我跑了两次测试)。所以它实际上最终更快让perl句柄根据需要分配数组。
<强>更新强>
在通过ysth建议进行更改后,数字更有意义:“推”方法为2.27秒,预分配为2.21秒。即使这样,我也会质疑这样的优化是否真的可以节省任何时间(100,000次迭代后差异仅为0.06秒)。
答案 3 :(得分:2)
你的方式很棒,DVK也是如此。在单个命令中执行此操作的方法可能是:
@array = (0 .. 49);
但是我不确定它是否更优雅,因为它为每个元素分配了1到49之间的值,但对于程序员来说,理解Perl的语法可能更直观。
答案 4 :(得分:2)
使用undef
代替特定值my @array;
$array[49] = undef;
答案 5 :(得分:1)
预分配可能对速度没有多大帮助,但如果分配的块足够大,它可能有助于将内存返回到系统
答案 6 :(得分:-1)
预定义数组长度的一个优点是,项目可以按任何方便的顺序填充,而不是按推送要求的严格顺序。这更不容易出错。