in reply to Re: How to print the 10 most recent (epoch) keys in a hash when epoch is not the key
in thread How to print the 10 most recent (epoch) keys in a hash when epoch is not the key
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
|
|---|