Perl 배열을 반복하는 가장 좋은 방법
Perl 배열을 반복하는 데 가장 적합한 구현 (속도 및 메모리 사용량 측면에서)은 무엇입니까? 더 좋은 방법이 있습니까? ( @Array
유지할 필요가 없습니다).
구현 1
foreach (@Array)
{
SubRoutine($_);
}
구현 2
while($Element=shift(@Array))
{
SubRoutine($Element);
}
구현 3
while(scalar(@Array) !=0)
{
$Element=shift(@Array);
SubRoutine($Element);
}
구현 4
for my $i (0 .. $#Array)
{
SubRoutine($Array[$i]);
}
구현 5
map { SubRoutine($_) } @Array ;
속도 측면에서 : # 1 및 # 4이지만 대부분의 경우 그다지 많지는 않습니다.
확인을 위해 벤치 마크를 작성할 수 있지만 반복 작업이 Perl 대신 C에서 수행되고 배열 요소의 불필요한 복사가 발생하지 않기 때문에 # 1과 # 4가 약간 더 빠르다고 생각합니다. ( # 1의 요소에 별칭
$_
이 지정 되지만 # 2 및 # 3은 실제로 배열에서 스칼라를 복사 합니다.)# 5는 비슷할 수 있습니다.
메모리 사용량 측면에서 : # 5를 제외하고 모두 동일합니다.
for (@a)
어레이를 평평하게하지 않도록 특수한 경우입니다. 루프는 배열의 인덱스를 반복합니다.가독성 측면에서 : # 1.
유연성 측면에서 : # 1 / # 4 및 # 5.
# 2는 거짓 요소를 지원하지 않습니다. # 2와 # 3은 파괴적입니다.
의 요소에만 관심이 있다면 다음을 @Array
사용하십시오.
for my $el (@Array) {
# ...
}
또는
인덱스가 중요한 경우 다음을 사용하십시오.
for my $i (0 .. $#Array) {
# ...
}
또는 perl
5.12.1부터 다음을 사용할 수 있습니다.
while (my ($i, $el) = each @Array) {
# ...
}
루프 본문에 요소와 색인이 모두 필요한 경우 나는 기대할 것이다 사용 each
가장 빠르지 만5.12.1 이전 버전과의 호환성을 포기하게됩니다 perl
.
이들 이외의 다른 패턴은 특정 상황에서 적절할 수 있습니다.
IMO, 구현 # 1은 일반적이며 Perl의 경우 짧고 관용적 인 것이 다른 것보다 우선합니다. 세 가지 선택에 대한 벤치 마크는 최소한 속도에 대한 통찰력을 제공 할 수 있습니다.
1 is substantially different from 2 and 3, since it leaves the array in tact, whereas the other two leave it empty.
I'd say #3 is pretty wacky and probably less efficient, so forget that.
Which leaves you with #1 and #2, and they do not do the same thing, so one cannot be "better" than the other. If the array is large and you don't need to keep it, generally scope will deal with it (but see NOTE), so generally, #1 is still the clearest and simplest method. Shifting each element off will not speed anything up. Even if there is a need to free the array from the reference, I'd just go:
undef @Array;
when done.
- NOTE: The subroutine containing the scope of the array actually keeps the array and re-uses the space next time. Generally, that should be fine (see comments).
In single line to print the element or array.
print $_ for (@array);
NOTE: remember that $_ is internally referring to the element of @array in loop. Any changes made in $_ will reflect in @array; ex.
my @array = qw( 1 2 3 );
for (@array) {
$_ = $_ *2 ;
}
print "@array";
output: 2 4 6
The best way to decide questions like this to benchmark them:
use strict;
use warnings;
use Benchmark qw(:all);
our @input_array = (0..1000);
my $a = sub {
my @array = @{[ @input_array ]};
my $index = 0;
foreach my $element (@array) {
die unless $index == $element;
$index++;
}
};
my $b = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (defined(my $element = shift @array)) {
die unless $index == $element;
$index++;
}
};
my $c = sub {
my @array = @{[ @input_array ]};
my $index = 0;
while (scalar(@array) !=0) {
my $element = shift(@array);
die unless $index == $element;
$index++;
}
};
my $d = sub {
my @array = @{[ @input_array ]};
foreach my $index (0.. $#array) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $e = sub {
my @array = @{[ @input_array ]};
for (my $index = 0; $index < $#array; $index++) {
my $element = $array[$index];
die unless $index == $element;
}
};
my $f = sub {
my @array = @{[ @input_array ]};
while (my ($index, $element) = each @array) {
die unless $index == $element;
}
};
my $count;
timethese($count, {
'1' => $a,
'2' => $b,
'3' => $c,
'4' => $d,
'5' => $e,
'6' => $f,
});
And running this on perl 5, version 24, subversion 1 (v5.24.1) built for x86_64-linux-gnu-thread-multi
I get:
Benchmark: running 1, 2, 3, 4, 5, 6 for at least 3 CPU seconds...
1: 3 wallclock secs ( 3.16 usr + 0.00 sys = 3.16 CPU) @ 12560.13/s (n=39690)
2: 3 wallclock secs ( 3.18 usr + 0.00 sys = 3.18 CPU) @ 7828.30/s (n=24894)
3: 3 wallclock secs ( 3.23 usr + 0.00 sys = 3.23 CPU) @ 6763.47/s (n=21846)
4: 4 wallclock secs ( 3.15 usr + 0.00 sys = 3.15 CPU) @ 9596.83/s (n=30230)
5: 4 wallclock secs ( 3.20 usr + 0.00 sys = 3.20 CPU) @ 6826.88/s (n=21846)
6: 3 wallclock secs ( 3.12 usr + 0.00 sys = 3.12 CPU) @ 5653.53/s (n=17639)
So the 'foreach (@Array)' is about twice as fast as the others. All the others are very similar.
@ikegami also points out that there are quite a few differences in these implimentations other than speed.
참고URL : https://stackoverflow.com/questions/10487316/best-way-to-iterate-through-a-perl-array
'Programing' 카테고리의 다른 글
명령 줄 도구가 설치된 Mavericks에서 xcodebuild를 사용할 수 없음 (0) | 2020.08.31 |
---|---|
파이썬 프로그램을 어떻게 배포 할 수 있습니까? (0) | 2020.08.31 |
Timertask 또는 핸들러 (0) | 2020.08.31 |
Android 라이브러리 프로젝트를 테스트하는 방법 (0) | 2020.08.31 |
Perl 어레이를 인쇄하는 쉬운 방법? (0) | 2020.08.30 |