Просто чтобы убедиться, что я протестировал решения grep и map, сначала выполняя поиск индексов соответствующих элементов (удаляемых), а затем непосредственно удаляя элементы с помощью grep без поиска индексов.
Похоже, что первое решение, предложенное Сэмом при задании его вопроса, было уже самым быстрым.
use Benchmark;
my @A=qw(A B C A D E A F G H A I J K L A M N);
my @M1; my @G; my @M2;
my @Ashrunk;
timethese( 1000000, {
'map1' => sub {
my $i=0;
@M1 = map { $i++; $_ eq 'A' ? $i-1 : ();} @A;
},
'map2' => sub {
my $i=0;
@M2 = map { $A[$_] eq 'A' ? $_ : () ;} 0..$#A;
},
'grep' => sub {
@G = grep { $A[$_] eq 'A' } 0..$#A;
},
'grem' => sub {
@Ashrunk = grep { $_ ne 'A' } @A;
},
});
Результат:
Benchmark: timing 1000000 iterations of grem, grep, map1, map2...
grem: 4 wallclock secs ( 3.37 usr + 0.00 sys = 3.37 CPU) @ 296823.98/s (n=1000000)
grep: 3 wallclock secs ( 2.95 usr + 0.00 sys = 2.95 CPU) @ 339213.03/s (n=1000000)
map1: 4 wallclock secs ( 4.01 usr + 0.00 sys = 4.01 CPU) @ 249438.76/s (n=1000000)
map2: 2 wallclock secs ( 3.67 usr + 0.00 sys = 3.67 CPU) @ 272702.48/s (n=1000000)
M1 = 0 3 6 10 15
M2 = 0 3 6 10 15
G = 0 3 6 10 15
Ashrunk = B C D E F G H I J K L M N
Как показывают прошедшие времена, бесполезно пытаться реализовать удаление
функция, использующая либо grep, либо карту определенных индексов. Просто grep-удалить напрямую.
До тестирования я думал, что "map1" будет наиболее эффективным ... Я должен чаще полагаться на Benchmark, я думаю. ; -)