Arrays 移位满足某些规则的值

Arrays 移位满足某些规则的值,arrays,perl,Arrays,Perl,我有一个数字数组,希望删除数组开头的所有非正数(即零或负数)。以下是我所拥有的: shiftlbl: $shift = shift @ary; if (0 >= $shift) {goto shiftlbl;} else {unshift @ary, $shift;} 有没有一种更好(更快)的方法,或者效果大致相同但更完美或更易于阅读的方法?您可以从以下位置使用after\u incl: 输出: 获取列表后,对其应用块,直到块返回true,并返回从该点到原始列表末尾的值列表。不使用任何模

我有一个数字数组,希望删除数组开头的所有非正数(即零或负数)。以下是我所拥有的:

shiftlbl:
$shift = shift @ary;
if (0 >= $shift) {goto shiftlbl;}
else {unshift @ary, $shift;}

有没有一种更好(更快)的方法,或者效果大致相同但更完美或更易于阅读的方法?

您可以从以下位置使用
after\u incl

输出:
获取列表后,对其应用块,直到块返回true,并返回从该点到原始列表末尾的值列表。

不使用任何模块,您可以使用

shift @ary while @ary && $ary[0] <= 0;
对于
-1000。。200
,我要

         Rate    old    new splice
old    2782/s     --   -62%   -69%
new    7371/s   165%     --   -17%
splice 8886/s   219%    21%     --
以下是全部代码:

#!/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();
#/usr/bin/perl
使用警告;
严格使用;
use List::Util qw{first};
使用测试::更多;
使用基准qw{cmpthese};
亚旧{
我的@ary=@;
移位BL:
我的$shift=shift@ary;
如果(0>=$shift){goto shiftlbl;}
else{unshift@ari,$shift;}
返回@ary
}
次新{
我的@ary=@;
在@ary&&$ary[0]0}0时移位@ary$#阿利;
拼接@ary,0,$i;
返回@ary
}
my@ar=(-1000..200);
是深([old(@ar)],[new(@ar)],'old-new');
是深([old(@ar)],[sp(@ar)],“old-splice”);
cmpthese(-5,
{
old=>sub{old(@ar)},
new=>sub{new(@ar)},
拼接=>sub{sp(@ar)},
#也尝试了类似的结果:
#old=>“old(-1000..200)”,
#新=>'新(-1000..200)',
#拼接=>“sp(-1000..200)”,
});
完成测试();

请显示您预期的输入和输出。@AruneshSingh,它在介绍性语句中。(但如果你需要一个例子,那就举个好例子。)哦,谢谢!(当然,我应该检查一下那个模块。)@ThisSuitesBlack不,我删除了我的评论(在你的评论发布之前),因为有迹象表明它是错误的,而自执行基准测试后显示它是错误的。List::MoreUtils和List::MoreUtils::XS是相同的代码。谢谢,如果你添加TSIBN的解决方案,你会发现它比第一个快,但比第二个慢。@ikegami当我添加
sub lmu{my@ary=@;ary=after_incl{$\u>0}@ary;return@ary;}
到choroba的基准测试中时,列表::MoreUtils比
拼接
解决方案快46%,比
while
循环快53%。我是不是把基准测试搞砸了,还是这里发生了什么事?@ThisSuitesBlacknot:奇怪。对我来说,它比旧的解决方案慢了2倍:——)@choroba非常奇怪。即使使用纯Perl版本,也会得到类似的结果(这两种情况下都比OP的原始代码快大约500%)。您使用的是什么版本的Perl和List::MoreUtils?我想知道在cygwin、Windows7、L::MU 0.413上的Perl5.22.0中是否有明显的调整。
use List::Util qw{ first };
my $i = first { $ary[$_] > 0 } 0 .. $#ary;
splice @ary, 0, $i;
         Rate    old    new splice
old    2782/s     --   -62%   -69%
new    7371/s   165%     --   -17%
splice 8886/s   219%    21%     --
#!/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();