Discussion:
Sub
(trop ancien pour répondre)
kurtz le pirate
2015-05-17 06:32:13 UTC
Permalink
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
Marc Espie
2015-05-17 07:46:45 UTC
Permalink
Post by kurtz le pirate
bonjour,
ca devient un peu vide ici... :(
bon, j'ai juste un problÚme de syntaxe.
sub UniqueElems {
my %seen;
}
@MyArray = UniqueElems (\@MyArray);
le perlsub n'est pas trés explicite sur ce point.
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;
}
Paul Gaborit
2015-05-17 13:02:25 UTC
Permalink
À (at) Sun, 17 May 2015 08:32:13 +0200,
Post by kurtz le pirate
bon, j'ai juste un problème de syntaxe.
sub UniqueElems {
my %seen;
}
@MyArray = UniqueElems (\@MyArray);
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 - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Jean-Louis Morel
2015-05-17 19:17:23 UTC
Permalink
Post by Paul Gaborit
Voici quatre possibilités. La 3e semble la plus rapide d'après les
résultats du benchmark.
[...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
Paul Gaborit
2015-05-17 21:49:04 UTC
Permalink
À (at) Sun, 17 May 2015 21:17:23 +0200,
Post by Jean-Louis Morel
Post by Paul Gaborit
Voici quatre possibilités. La 3e semble la plus rapide d'après les
résultats du benchmark.
[...couic]
Le module List::MoreUtils a une fonction 'uniq' qui fait tout le
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).
Bien vu. J'avais jeté un œil à List::Util (qui ne propose pas de
fonction 'uniq') mais j'avais oublié List::Module.
--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
Paul Gaborit
2015-05-17 21:57:20 UTC
Permalink
À (at) Sun, 17 May 2015 23:49:04 +0200,
Post by Paul Gaborit
Bien vu. J'avais jeté un œil à List::Util (qui ne propose pas de
fonction 'uniq') mais j'avais oublié List::Module.
^^^^^^^^^^^^^
List::MoreUtils
--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
kurtz le pirate
2015-05-17 20:10:44 UTC
Permalink
Post by Paul Gaborit
Voici quatre possibilités. La 3e semble la plus rapide d'après les
résultats du benchmark.
... 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
Paul Gaborit
2015-05-17 21:52:01 UTC
Permalink
À (at) Sun, 17 May 2015 22:10:44 +0200,
Post by kurtz le pirate
Post by Paul Gaborit
Voici quatre possibilités. La 3e semble la plus rapide d'après les
résultats du benchmark.
... 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% --
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).
Post by kurtz le pirate
le truc est de passer la référence par $a = shift;
Ça, c'est expliqué en détail dans 'perlref'...
--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
Perl en français - <http://perl.mines-albi.fr/>
kurtz le pirate
2015-05-18 08:34:19 UTC
Permalink
[snip]
Post by kurtz le pirate
le truc est de passer la référence par $a = shift;
Ça, c'est expliqué en détail dans 'perlref'...
grrr... j'avais regardé dans le perlsub :(




---
Kurtz le pirate
Compagnie de la Banquise

Continuer la lecture sur narkive:
Loading...