2 votes

Façon appropriée de retourner un arrayref à partir d'un sub avec un tri optionnel en Perl version 5.20

J'essaie d'écrire une sous-routine sous Perl 5 version 5.20, qui crée une grande liste de répertoires stockée dans un tableau. La sous-routine retourne le résultat sous la forme d'une arrayref. Pour des raisons pratiques, je veux avoir la possibilité de trier le résultat.

#!/usr/bin/env perl
use v5.20;
use warnings;
use strict;
use File::Slurp qw(read_dir);
use Time::HiRes;

use feature qw(signatures);
no warnings 'once';
no warnings 'experimental';
no warnings 'experimental::signatures';

my $PATH='/net/dbfs/GRM-RS/Flight-Campaigns/2021-08-23.Ram-Head-i-22.SE-01/cam/MM010259/iiq/';

sub fsReadDir($base, $sort, $mode = 1) {
    $base    //= '.';         # Base path default is the current path
    $sort    //= 0;           # Flag for array sorting of the result 
    my @res=read_dir($base);
    if ($sort) {
       return [sort(@res)] if $mode == 1;
       if ($mode == 2)  {
           @res = sort(@res);
           return \@res;
       }
    } else {  
        return \@res;
    } 
}

sub testSorting($sort, $mode, $max = 1000) {
    my $start = [Time::HiRes::gettimeofday()];   
    my $count = 0;
    for my $ix (0..$max) {
        my $array = fsReadDir($PATH, $sort, $mode );
        $count = @$array;
    }
    my $end   = time();
    my $dif = Time::HiRes::tv_interval($start);
    print "SORT: $sort MODE: $mode COUNT: $count TIME: $dif s\n"
}

testSorting(0, 1);
testSorting(1, 1);
testSorting(1, 2);

Résultats

/usr/bin/env perl "test-array.pl"
SORT: 0 MODE: 1 COUNT: 14861 TIME: 6.882694 s
SORT: 1 MODE: 1 COUNT: 14861 TIME: 9.131504 s
SORT: 1 MODE: 2 COUNT: 14861 TIME: 8.622628 s

Quelle est la manière efficace de trier le tableau directement au niveau du return niveau ?

3voto

zdim Points 29788

Si vous insistez pour que l'activité de triage se déroule dans la return elle-même peut utiliser une déclaration ternaire

return $sort ? [ sort @res ] : \@res;

Cela peut être très bien et assez clair dans des cas simples.

Cependant, je trouve plus clair de traiter d'abord les cas et les options, puis de renvoyer le résultat.

@res = sort @res if $sort;

if    ($mode == 1) { ... }   # modes given in the question do nearly the same,
elsif ($mode == 2) { ... }   # but imagine different processing based on value
...

return \@res;

De plus, le tri sur place devrait être un peu plus efficace.

S'il s'agissait d'efficacité, il faudrait évaluer différentes approches, dans des circonstances réalistes. D'une part, la lecture d'un grand répertoire peut faire sortir tout cela de l'eau, alors qu'il est possible que l'on ne puisse pas distinguer de différence de performance dans la façon dont le retour est construit exactement.

J'opterais donc pour la clarté, jusqu'à ce que l'on voie clairement que le choix affecte les performances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X