Sub
Le
kurtz le pirate

bonjour,
ca devient un peu vide ici :(
bon, j'ai juste un problème de syntaxe.
j'ai ce sous-programme :
sub UniqueElems {
my @thisArray = @{$_[0]};
my %seen;
return grep { not $seen{$_} ++ } @thisArray;
}
que j'utilise comme ça :
@MyArray = UniqueElems (@MyArray);
comment modifier mon UniqueElems pour que je puiss écrire directement :
UniqueElems (@MyArray);
le perlsub n'est pas trés explicite sur ce point.
merci.
kurtz le pirate
compagnie de la banquise
ca devient un peu vide ici :(
bon, j'ai juste un problème de syntaxe.
j'ai ce sous-programme :
sub UniqueElems {
my @thisArray = @{$_[0]};
my %seen;
return grep { not $seen{$_} ++ } @thisArray;
}
que j'utilise comme ça :
@MyArray = UniqueElems (@MyArray);
comment modifier mon UniqueElems pour que je puiss écrire directement :
UniqueElems (@MyArray);
le perlsub n'est pas trés explicite sur ce point.
merci.
kurtz le pirate
compagnie de la banquise
Je vois pas ce que perlsub viendrait faire sur un probleme de syntaxe
de references, hein.
sub UniqueElems {
my $r = shift;
my %seen;
@$r = grep { not $seen{$_} ++ } @$r;
}
kurtz le pirate
Voici quatre possibilités. La 3e semble la plus rapide d'après les
résultats du benchmark.
#!/usr/bin/perl -w
use strict;
use warnings;
use Benchmark qw(:all);
sub UniqueElems {
my $a = shift;
my %seen;
@$a = grep { not $seen{$_} ++ } @$a;
}
sub UniqueElems2 {
my $a = shift;
@$a = keys %{{map {$_ => 1} @$a}};
}
sub UniqueElems3 {
my $a = shift;
my %seen;
$seen{$_}++ foreach @$a;
@$a = keys %seen;
}
sub UniqueElems4 {
my $a = shift;
my %seen;
my @res;
foreach (@$a) {
push @res, $_ if $seen{$_}++;
}
@$a = @res;
}
my @values = map {int(rand(1000))} 1..10000;
cmpthese(-3, {
'UniqueElems' => sub {
my @MyArray = @values;
UniqueElems(@MyArray);
},
'UniqueElems2' => sub {
my @MyArray = @values;
UniqueElems2(@MyArray);
},
'UniqueElems3' => sub {
my @MyArray = @values;
UniqueElems3(@MyArray);
},
'UniqueElems4' => sub {
my @MyArray = @values;
UniqueElems4(@MyArray);
},
});
--
Paul Gaborit - Perl en français -
[...couic]
Le module List::MoreUtils a une fonction 'uniq' qui fait tout le
boulot :
http://search.cpan.org/dist/List-MoreUtils/lib/List/MoreUtils.pm#uniq_LIST
Je propose la fonction UniqueElems5 suivante qui semble juste un
chouia plus rapide que UniqueElems3 (en utilisant l'implémentation
xs du module ce qui est normalement fait par défaut).
#!/usr/bin/perl
use strict;
use warnings;
use List::MoreUtils 'uniq';
sub UniqueElems5 {
@{$_[0]} = uniq @{$_[0]};
}
--
JL
http://www.bribes.org/perl
... la différence n'est pas flagrante entre 1 et 3
Rate UniqueElems4 UniqueElems2 UniqueElems UniqueElems3
UniqueElems4 120/s -- -46% -57% -57%
UniqueElems2 221/s 84% -- -21% -21%
UniqueElems 279/s 132% 26% -- -0%
UniqueElems3 280/s 133% 26% 0% --
en fait, merci à tous.
le truc est de passer la référence par $a = shift;
et de modifier le tableau in situ avec le @$a.
---
Kurtz le pirate
Compagnie de la Banquise
Jean-Louis Morel
Bien vu. J'avais jeté un œil à List::Util (qui ne propose pas de
fonction 'uniq') mais j'avais oublié List::Module.
--
Paul Gaborit - Perl en français -
kurtz le pirate
Sur une liste de 10000 éléments, c'est moins visible. Mais dès qu'on
travaille sur de petites listes, la différence est plus importante. Et
la fonction 'uniq' de List::MoreUtils reste toujours la plus rapide
(sans compter qu'il n'y a pas à la maintenir).
Ça, c'est expliqué en détail dans 'perlref'...
--
Paul Gaborit - Perl en français -
Paul Gaborit
^^^^^^^^^^^^^
List::MoreUtils
--
Paul Gaborit - Perl en français -