我有一个数字数组,并希望删除数组开头的所有非正数(即零或负数).这就是我所拥有的:
shiftlbl:
$shift = shift @ary;
if (0 >= $shift) {goto shiftlbl;}
else {unshift @ary, $shift;}
Run Code Online (Sandbox Code Playgroud)
有没有一种方法更好(更快),或者工作方式大致相同,但更多Perlish或更容易阅读?
不使用任何模块,您可以使用
shift @ary while @ary && $ary[0] <= 0;
Run Code Online (Sandbox Code Playgroud)
它不仅更具可读性; 它也快得多.
或者,您可以尝试仅更改一次数组,如果要删除的部分很长,可以加快进程:
use List::Util qw{ first };
my $i = first { $ary[$_] > 0 } 0 .. $#ary;
splice @ary, 0, $i;
Run Code Online (Sandbox Code Playgroud)
因为-1000 .. 200,我得到了
Rate old new splice
old 2782/s -- -62% -69%
new 7371/s 165% -- -17%
splice 8886/s 219% 21% --
Run Code Online (Sandbox Code Playgroud)
这是整个代码:
#!/usr/bin/perl
use warnings;
use strict;
use List::Util qw{ first };
use Test::More;
use Benchmark qw{ cmpthese };
sub old {
my @ary = @_;
shiftlbl:
my $shift = shift @ary;
if (0 >= $shift) {goto shiftlbl;}
else {unshift @ary, $shift;}
return @ary
}
sub new {
my @ary = @_;
shift @ary while @ary && $ary[0] <= 0;
return @ary
}
sub sp {
my @ary = @_;
my $i = first { $ary[$_] > 0 } 0 .. $#ary;
splice @ary, 0, $i;
return @ary
}
my @ar = (-1000 .. 200);
is_deeply([old(@ar)], [new(@ar)], 'old - new');
is_deeply([old(@ar)], [sp(@ar)], 'old - splice');
cmpthese(-5,
{
old => sub { old(@ar) },
new => sub { new(@ar) },
splice => sub { sp(@ar) },
# Also tried with similar results:
# old => 'old( -1000 .. 200)',
# new => 'new( -1000 .. 200)',
# splice => 'sp( -1000 .. 200)',
});
done_testing();
Run Code Online (Sandbox Code Playgroud)