在 Perl 版本 5.20 中使用可选排序的子 return arrayref 的适当方法
Appropriate way to return an arrayref from a sub with optional sorting in Perl version 5.20
我尝试在 Perl 5 版本 5.20 下编写一个子例程,它创建一个存储在数组中的大目录列表。子例程 returns 将结果作为 arrayref。为方便起见,我希望可以选择对结果进行排序。
#!/usr/bin/env perl
use v5.20;
use warnings;
use strict;
use File::Slurp qw(read_dir);
use Time::HiRes;
use feature qw(signatures);
no warnings 'once';
no warnings 'experimental';
no warnings 'experimental::signatures';
my $PATH='/net/dbfs/GRM-RS/Flight-Campaigns/2021-08-23.Ram-Head-i-22.SE-01/cam/MM010259/iiq/';
sub fsReadDir($base, $sort, $mode = 1) {
$base //= '.'; # Base path default is the current path
$sort //= 0; # Flag for array sorting of the result
my @res=read_dir($base);
if ($sort) {
return [sort(@res)] if $mode == 1;
if ($mode == 2) {
@res = sort(@res);
return \@res;
}
} else {
return \@res;
}
}
sub testSorting($sort, $mode, $max = 1000) {
my $start = [Time::HiRes::gettimeofday()];
my $count = 0;
for my $ix (0..$max) {
my $array = fsReadDir($PATH, $sort, $mode );
$count = @$array;
}
my $end = time();
my $dif = Time::HiRes::tv_interval($start);
print "SORT: $sort MODE: $mode COUNT: $count TIME: $dif s\n"
}
testSorting(0, 1);
testSorting(1, 1);
testSorting(1, 2);
结果
/usr/bin/env perl "test-array.pl"
SORT: 0 MODE: 1 COUNT: 14861 TIME: 6.882694 s
SORT: 1 MODE: 1 COUNT: 14861 TIME: 9.131504 s
SORT: 1 MODE: 2 COUNT: 14861 TIME: 8.622628 s
直接在return
层排序数组的有效方法是什么?
如果坚持在return
语句中排序业务本身可以使用三元
return $sort ? [ sort @res ] : \@res;
在简单的情况下,这可能已经足够清楚了。
但是,我发现先处理案例和选项然后return结果
更清楚
@res = sort @res if $sort;
if ($mode == 1) { ... } # modes given in the question do nearly the same,
elsif ($mode == 2) { ... } # but imagine different processing based on value
...
return \@res;
此外,就地排序应该会更高效一些。
如果这与效率有关,那么您需要在现实情况下对不同的方法进行基准测试。其一,当一个人可能无法分辨 return 的构造方式的任何性能差异时,它可能会通过读取一个大目录而全部被吹出水面。
所以我会为了清楚起见,直到清楚地看到选择确实会影响性能。
我尝试在 Perl 5 版本 5.20 下编写一个子例程,它创建一个存储在数组中的大目录列表。子例程 returns 将结果作为 arrayref。为方便起见,我希望可以选择对结果进行排序。
#!/usr/bin/env perl
use v5.20;
use warnings;
use strict;
use File::Slurp qw(read_dir);
use Time::HiRes;
use feature qw(signatures);
no warnings 'once';
no warnings 'experimental';
no warnings 'experimental::signatures';
my $PATH='/net/dbfs/GRM-RS/Flight-Campaigns/2021-08-23.Ram-Head-i-22.SE-01/cam/MM010259/iiq/';
sub fsReadDir($base, $sort, $mode = 1) {
$base //= '.'; # Base path default is the current path
$sort //= 0; # Flag for array sorting of the result
my @res=read_dir($base);
if ($sort) {
return [sort(@res)] if $mode == 1;
if ($mode == 2) {
@res = sort(@res);
return \@res;
}
} else {
return \@res;
}
}
sub testSorting($sort, $mode, $max = 1000) {
my $start = [Time::HiRes::gettimeofday()];
my $count = 0;
for my $ix (0..$max) {
my $array = fsReadDir($PATH, $sort, $mode );
$count = @$array;
}
my $end = time();
my $dif = Time::HiRes::tv_interval($start);
print "SORT: $sort MODE: $mode COUNT: $count TIME: $dif s\n"
}
testSorting(0, 1);
testSorting(1, 1);
testSorting(1, 2);
结果
/usr/bin/env perl "test-array.pl"
SORT: 0 MODE: 1 COUNT: 14861 TIME: 6.882694 s
SORT: 1 MODE: 1 COUNT: 14861 TIME: 9.131504 s
SORT: 1 MODE: 2 COUNT: 14861 TIME: 8.622628 s
直接在return
层排序数组的有效方法是什么?
如果坚持在return
语句中排序业务本身可以使用三元
return $sort ? [ sort @res ] : \@res;
在简单的情况下,这可能已经足够清楚了。
但是,我发现先处理案例和选项然后return结果
更清楚@res = sort @res if $sort;
if ($mode == 1) { ... } # modes given in the question do nearly the same,
elsif ($mode == 2) { ... } # but imagine different processing based on value
...
return \@res;
此外,就地排序应该会更高效一些。
如果这与效率有关,那么您需要在现实情况下对不同的方法进行基准测试。其一,当一个人可能无法分辨 return 的构造方式的任何性能差异时,它可能会通过读取一个大目录而全部被吹出水面。
所以我会为了清楚起见,直到清楚地看到选择确实会影响性能。