以下是代码...
use strict;
use warnings;
my @array= (1,2,3,4,5);
my $scalar= 5;
@array= $scalar*@array;
print @array;
需要一些能够用少量代码实现类似功能的东西。谢谢!
使用 foreach 循环。
foreach my $x (@array) { $x = $x * $scalar; }
foreach
方法比map
方法更快。 - Alex Reynoldsmap
的并行处理是 Perl 6 可能会采用的一项功能,但它很可能永远不会出现在 Perl 5 中。太多的代码依赖于 map 语句的有序迭代。Perl 5 的副作用过重,使得 perl
无法识别哪些 map 函数体是完全没有副作用的。 - Ven'Tatsu你可以尝试这样做:
@array = map { $_ * $scalar } @array;
更简单地说:map { $_ *= $scalar } @array;
$_ *= $scalar for @array;
。 - ikegami如何实现:
foreach(@array)
{ $_ *= $scalar }
正如您所看到的,您可以在遍历数组时就地修改它。
我不知道你的需求范围。如果你正在进行数字数据处理,那么Perl数据语言(PDL)可以将数字数据数组转换为“piddle”对象,并重载数学运算符以“向量化”它们的操作。这是进行数字处理非常高效的系统。以下是一个示例:
#!/usr/bin/perl
use strict;
use warnings;
use PDL;
my $pdl_array = pdl([1,1,2,3,5,8]);
print 2*$pdl_array;
__END__
gives:
[2 2 4 6 10 16]
map
方法的测试:#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my @array = ();
push(@array, (1) x 1000000);
my $scalar = 5;
my $startTime = new Benchmark();
@array = map { $_ * $scalar } @array;
my $stopTime = new Benchmark();
print STDOUT "runtime: ".timestr(timediff($stopTime, $startTime), 'all')." sec\n";
以下是使用foreach
方法的测试:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my @array = ();
push(@array, (1) x 1000000);
my $scalar = 5;
my $startTime = new Benchmark();
foreach my $x (@array) { $x = $x * $scalar; }
my $stopTime = new Benchmark();
print STDOUT "runtime: ".timestr(timediff($stopTime, $startTime), 'all')." sec\n";
以下是我的系统信息:
bash-3.2$ perl --version
This is perl, v5.8.8 built for darwin-2level
...
bash-3.2$ uname -a
Darwin Sounder.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386
以下是一次测试的结果:
bash-3.2$ ./test.map.pl
runtime: 4 wallclock secs ( 0.41 usr 0.70 sys + 0.00 cusr 0.00 csys = 1.11 CPU) sec
bash-3.2$ ./test.foreach.pl
runtime: 0 wallclock secs ( 0.13 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.13 CPU) sec
这些时间在同一台机器上是相对可重复的,并且在双核Linux机器上的结果有些可重复:
[areynolds@fiddlehead ~]$ perl --version
This is perl, v5.8.8 built for x86_64-linux-thread-multi
...
[areynolds@fiddlehead ~]$ uname -a
Linux fiddlehead.example.com 2.6.18-194.17.1.el5 #1 SMP Mon Sep 20 07:12:06 EDT 2010 x86_64 GNU/Linux
[areynolds@fiddlehead ~]$ ./test.map.pl
runtime: 0 wallclock secs ( 0.28 usr 0.05 sys + 0.00 cusr 0.00 csys = 0.33 CPU) sec
[areynolds@fiddlehead ~]$ ./test.foreach.pl
runtime: 0 wallclock secs ( 0.09 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.09 CPU) sec
map
比foreach
的性能慢了8.53倍。在Linux系统上,同样的操作,速度慢了3.67倍。map
仍然比foreach
表现差。sounder:~ alexreynolds$ perl --version
This is perl 5, version 12, subversion 3 (v5.12.3) built for darwin-multi-2level
...
sounder:~ alexreynolds$ ./test.map.pl
runtime: 0 wallclock secs ( 0.45 usr 0.08 sys + 0.00 cusr 0.00 csys = 0.53 CPU) sec
sounder:~ alexreynolds$ ./test.foreach.pl
runtime: 1 wallclock secs ( 0.18 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.18 CPU) sec
这个数值从变差了8.53倍到变差了2.94倍,改善相当显著。
将Perl安装升级到v5.12.2后,Linux系统的表现略微变差:
[areynolds@basquiat bin]$ perl --version
This is perl 5, version 12, subversion 2 (v5.12.2) built for x86_64-linux-thread-multi
...
[areynolds@basquiat bin]$ /home/areynolds/test.map.pl
runtime: 1 wallclock secs ( 0.29 usr 0.07 sys + 0.00 cusr 0.00 csys = 0.36 CPU) sec
[areynolds@basquiat bin]$ /home/areynolds/test.foreach.pl
runtime: 0 wallclock secs ( 0.08 usr 0.00 sys + 0.00 cusr 0.00 csys = 0.08 CPU) sec
对我来说,很不幸的是Larry没有允许
$scalar operator (list)
或者
(list) operator $scalar
当然,map或循环也可以实现,但以上语法更加简洁。
如果两个列表长度相等,(list) operator (list) 也是有意义的。
惊讶于Larry没有允许这些,只是说一下...我猜在这种情况下还有(n-1)种方法可以实现。
比如
my @a = 'n' . (1..5); my @a = 2 * (1..5);
甚至
my @a = 2 * @b;