Simple way to get all the hash keys in epoch sorted order:

Not quite simple enough! You don't need the added complication of a Schwartzian transform here as the item you are sorting on is already available rather than being obtained via some expensive transaction. Here a ST only slows things down.

In the following two benchmarks we are sorting files by their epoch modification date. In the first we have a hash of files as key and their epoch modification times as value which are sorted both via direct hash lookup and via a ST. Note how the ST is slower.

use strict; use warnings; use File::Find; use Benchmark qw { cmpthese }; my %files = (); my $rcWanted = sub { $files{ $File::Find::name } = ( lstat $File::Find::name )[ 9 ]; }; find( $rcWanted, q{/usr/bin} ); cmpthese( -5, { Direct => sub { my $raSorted = useDirect() }, ST => sub { my $raSorted = useST() }, } ); sub useDirect { my @sorted = sort { $files{ $b } <=> $files{ $a } } keys %files; return \ @sorted; } sub useST { my @sorted = map { $_->[ 0 ] } sort { $b->[ 1 ] <=> $a->[ 1 ] } map { [ $_, $files{ $_ } ] } keys %files; return \ @sorted; }

The output.

Rate ST Direct ST 35.8/s -- -37% Direct 56.9/s 59% --

If we now change the code for the second benchmark so that we just have an array of filenames, we have to do the "expensive" inode look-up to get the modification time as part of the sort code. Now the ST makes sense as it avoids the repetitive lstat calls for each file as the sort algorithm moves the file into its correct position.

use strict; use warnings; use File::Find; use Benchmark qw { cmpthese }; my @files = (); my $rcWanted = sub { push @files, $File::Find::name; }; find( $rcWanted, q{/usr/bin} ); cmpthese( -5, { Direct => sub { my $raSorted = useDirect() }, ST => sub { my $raSorted = useST() }, } ); sub useDirect { my @sorted = sort { lstat( $b ) <=> lstat( $a ) } @files; return \ @sorted; } sub useST { my @sorted = map { $_->[ 0 ] } sort { $b->[ 1 ] <=> $a->[ 1 ] } map { [ $_, lstat( $_ ) ] } @files; return \ @sorted; }

The output.

Rate Direct ST Direct 1.29/s -- -46% ST 2.38/s 85% --

I hope this is of interest.

Cheers,

JohnGG


In reply to Re^2: How to print the 10 most recent (epoch) keys in a hash when epoch is not the key by johngg
in thread How to print the 10 most recent (epoch) keys in a hash when epoch is not the key by kevyt

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.