$found = 0; @list = grep { $item ne $_ || $found++ } @list; #### my ($index) = grep { $item eq $list[$_] } 0..$#list; splice(@list, $index, 1) if defined $index; #### use List::Util qw( first ); my $index = first { $item eq $list[$_] } 0..$#list; splice(@list, $index, 1) if defined $index; #### use strict; use warnings; use Benchmark qw( cmpthese ); use List::Util qw( first ); use List::MoreUtils qw( first_index ); my @short = qw( c a b c d b c d c ); my @med = map { chr(ord('a') + rand(26)) } 0..100; my @long = map { chr(ord('a') + rand(26)) } 0..1000; sub grep_alone { my ($item, @list) = @_; my $found = 0; @list = grep { $item ne $_ || $found++ } @list; return @list; } sub grep_splice { my ($item, @list) = @_; my ($index) = grep { $item eq $list[$_] } 0..$#list; splice(@list, $index, 1) if defined $index; return @list; } sub grep_splice_2 { my ($item, @list) = @_; my $found = 0; my ($index) = grep { $item eq $list[$_] && !($found++) } 0..$#list; splice(@list, $index, 1) if defined $index; return @list; } sub first_splice { my ($item, @list) = @_; my $index = first { $item eq $list[$_] } 0..$#list; splice(@list, $index, 1) if defined $index; return @list; } sub findex_splice { my ($item, @list) = @_; my $index = first_index { $item eq $_ } @list; splice(@list, $index, 1) if $index >= 0; return @list; } print("Verify:\n\n"); print('grep_alone: ', (grep_alone @short), "\n"); print('grep_splice: ', (grep_splice @short), "\n"); print('grep_splice_2: ', (grep_splice_2 @short), "\n"); print('first_splice: ', (first_splice @short), "\n"); print('findex_splice: ', (findex_splice @short), "\n"); print("\n\n"); print("\@short:\n\n"); cmpthese(-1, { grep_alone => sub { grep_alone @short; 1; }, grep_splice => sub { grep_splice @short; 1; }, grep_splice_2 => sub { grep_splice_2 @short; 1; }, first_splice => sub { first_splice @short; 1; }, findex_splice => sub { findex_splice @short; 1; }, }); print("\n\n"); print("\@med:\n\n"); cmpthese(-1, { grep_alone => sub { grep_alone @med; 1; }, grep_splice => sub { grep_splice @med; 1; }, grep_splice_2 => sub { grep_splice_2 @med; 1; }, first_splice => sub { first_splice @med; 1; }, findex_splice => sub { findex_splice @med; 1; }, }); print("\n\n"); print("\@long:\n\n"); cmpthese(-1, { grep_alone => sub { grep_alone @long; 1; }, grep_splice => sub { grep_splice @long; 1; }, grep_splice_2 => sub { grep_splice_2 @long; 1; }, first_splice => sub { first_splice @long; 1; }, findex_splice => sub { findex_splice @long; 1; }, }); print("\n\n"); print("The XS versions of List::Util and List::MoreUtils were used.\n"); #### Verify: grep_alone: abdbcdc grep_splice: abdbcdc grep_splice_2: abdbcdc first_splice: abdbcdc findex_splice: abdbcdc @short: Rate first_splice findex_splice grep_splice_2 grep_alone grep_splice first_splice 25097/s -- -19% -38% -39% -44% findex_splice 31152/s 24% -- -22% -24% -30% grep_splice_2 40193/s 60% 29% -- -2% -10% grep_alone 41059/s 64% 32% 2% -- -8% grep_splice 44790/s 78% 44% 11% 9% -- @med: Rate first_splice grep_alone findex_splice grep_splice_2 grep_splice first_splice 4218/s -- -7% -20% -25% -27% grep_alone 4517/s 7% -- -14% -20% -22% findex_splice 5278/s 25% 17% -- -6% -9% grep_splice_2 5624/s 33% 25% 7% -- -3% grep_splice 5816/s 38% 29% 10% 3% -- @long: Rate grep_alone grep_splice_2 grep_splice first_splice findex_splice grep_alone 457/s -- -23% -25% -56% -66% grep_splice_2 593/s 30% -- -3% -42% -55% grep_splice 610/s 34% 3% -- -41% -54% first_splice 1027/s 125% 73% 68% -- -23% findex_splice 1331/s 191% 124% 118% 30% -- The XS versions of List::Util and List::MoreUtils were used.