Как мне умножить каждый член массива на скаляр в Perl? - PullRequest
9 голосов
/ 15 апреля 2011

Вот код ...

use strict;
use warnings;

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

@array= $scalar*@array;

print @array;

Нужно что-то, что может выполнять аналогичную функцию с небольшим количеством кода. Спасибо!

Ответы [ 5 ]

10 голосов
/ 15 апреля 2011

Используйте foreach.

foreach my $x (@array) { $x = $x * $scalar; }
9 голосов
/ 15 апреля 2011

Вы можете попробовать это:

@array = map { $_ * $scalar } @array;

или более просто:

map { $_ *= $scalar } @array;
7 голосов
/ 15 апреля 2011

Как это:

foreach(@array)
{ $_ *= $scalar }

Как видите, вы можете изменить массив на месте, когда он пройден.

5 голосов
/ 16 апреля 2011

Я не знаю сферу ваших потребностей. Если вы выполняете числовые манипуляции с данными, язык данных 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]
4 голосов
/ 15 апреля 2011

Этот комментарий предназначен для SoloBold.

Вот тест подхода 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

Соотношение производительности на OS X в 8,53 раза ниже для map против foreach.На Linux box 3.67x медленнее для того же.

Мой Linux-блок является двухъядерным и имеет несколько более быстрые ядра, чем мой одноядерный ноутбук с OS X.

EDIT

Я обновил Perlс v8.8.8 до v5.12.3 на моем OS X box и получил значительное увеличение скорости, но 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.53x хуже до 2.94xхуже.Достаточно существенное улучшение.

Linux работал немного хуже с обновлением его установки Perl до v5.12.2:

[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

Это идет с 3.67x хуже до 4.5х хуже - не так хорошо!Это может не всегда платить за апгрейд, просто ради этого.

...