in reply to Sort the file names a list

Sounds like you need a custom sort routine. There are several ways you could do it. Most simply (and least efficiently):

my @sorted = sort { (split /\./, $a)[1] cmp (split /\./, $b)[1] } @LogAnalyser::LogFileList;

A better way (that someone named something fancy which I cannot remember):

my @sorted = sort datestamp @LogAnalyser::LogFileList; { # anonymous block. If you're using Perl 5.10, you could # use a state variable instead. my %cache; sub datestamp { my $left = ( $cache{$a} ||= (split /\./, $a)[1] ); my $right = ( $cache{$b} ||= (split /\./, $b)[1] ); return $left cmp $right; } }

This last one does a little memory tradeoff to avoid doing the split and offset twice for every comparison in the sort.

$,=' ';$\=',';$_=[qw,Just another Perl hacker,];print@$_;

Replies are listed 'Best First'.
Re^2: Sort the file names a list
by ikegami (Patriarch) on Aug 31, 2009 at 16:31 UTC

    A better way (that someone named something fancy which I cannot remember):

    Memoizing is caching the result of a function based on its inputs. You're memoizing split.


    Less of a tradeoff:

    my @sorted = map substr($_, 19), sort map substr($_, -(19+20), 19) . $_, @LogAnalyser::LogFileList;

    For the data posted in the OP:

    Rate memoized st naive grt memoized 12517/s -- -30% -64% -66% st 17883/s 43% -- -48% -52% naive 34555/s 176% 93% -- -6% grt 36872/s 195% 106% 7% --

    Update: Added ST.
    Update: Fixed bug in substr indexes.

      ikegami++! I'd seen the GRT discussed, but never tried it myself. I guess I never thought enough about it, and my first-glance assessment was that memoization was faster. That'll teach me to make assumptions without testing!

      Oh, and I saw the memoization technique called the "Orcish (or-cache) maneuver" in Perl Underground 2 (credit japhy).

      $,=' ';$\=',';$_=[qw,Just another Perl hacker,];print@$_;
        I had a bug. Fixing it affected the times. You'll note that your solution actually slows down the sorting.
      ikegami, I know you already know it, but reading your post somebody could thing that using the your GRT code is a good idea because it is the faster solution when actually it is not!

      It is not good because using substr() to extract the sorting keys is very weak. If for instance, the file names extensions are changed, it will extract incorrect keys and, what is worst, without reporting any warning or error to the user!

      Even if slower, using a regular expression to extract the keys is probably the best solution.

      In any case, there is a faster (not recommendable either) method...

      ... use Sort::Key qw(keysort); ... cmpthese(-3, { ... sk => ' use strict; use warnings; my @sorted = keysort { substr($_, -(19+20), 19) } @::LogFileLi +st; ', });
      that on my computer runs as...
      Rate memoized st grt naive sk memoized 8784/s -- -26% -51% -54% -58% st 11894/s 35% -- -33% -38% -43% grt 17794/s 103% 50% -- -7% -14% naive 19207/s 119% 61% 8% -- -7% sk 20714/s 136% 74% 16% 8% --
      Note also that on my hardware, naive is actually faster than grt.

        What?

        First of all, do you have a problem with GRT or substr? You said GRT, but you talk of the substr I used for key extraction in all methods.

        Secondly, if the spec changes, of course the code will need to be changed. I don't see that as a problem. Switching to using a regex match is not going to help this.

        So, no, I don't "already know it".