Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Sub

7 réponses
Avatar
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

7 réponses

Avatar
espie
In article <555835ed$0$2978$,
kurtz le pirate wrote:
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.


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;
}
Avatar
Paul Gaborit
À (at) Sun, 17 May 2015 08:32:13 +0200,
kurtz le pirate écrivait (wrote):

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);



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/>
Avatar
Jean-Louis Morel
Le 17/05/2015 15:02, Paul Gaborit a écrit :

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
Avatar
kurtz le pirate
Le 17/05/2015 15:02, Paul Gaborit a écrit :
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
Avatar
Paul Gaborit
À (at) Sun, 17 May 2015 21:17:23 +0200,
Jean-Louis Morel écrivait (wrote):

Le 17/05/2015 15:02, Paul Gaborit a écrit :

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).



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/>
Avatar
Paul Gaborit
À (at) Sun, 17 May 2015 22:10:44 +0200,
kurtz le pirate écrivait (wrote):

Le 17/05/2015 15:02, Paul Gaborit a écrit :
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).

le truc est de passer la référence par $a = shift;
et de modifier le tableau in situ avec le @$a.



Ç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/>
Avatar
Paul Gaborit
À (at) Sun, 17 May 2015 23:49:04 +0200,
Paul Gaborit écrivait (wrote):
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/>