@files = sort { my ($ad) = ( $a =~ /fwlog\.(\d+)\w+/ ); my ($bd) = ( $b =~ /fwlog\.(\d+)\w+/ ); $ad <=> $bd } @files; #### foo1.tla foo10.tla foo100.tla foo101.tla foo102.tla etc. #### sub naive { sort { my ( $ma ) = $a =~ /foo(\d+)\.tla/; my ( $mb ) = $b =~ /foo(\d+)\.tla/; $ma <=> $mb } @_; } #### sub orcish { my %c; sort { $c{$a} or ( $c{$a} ) = $a =~ /foo(\d+)\.tla/; $c{$b} or ( $c{$b} ) = $b =~ /foo(\d+)\.tla/; $c{$a} <=> $c{$b}; } @_; } #### sub schwartzian { map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, /foo(\d+)\.tla/ ] } @_; } #### sub guttros { map { substr( $_, 3 ) } sort map { sprintf( "%03d", /foo(\d+)\.tla/ ) . $_ } @_; } #### Benchmark: timing 5000 iterations of guttros, naive, orcish, schwartzian... guttros: 14 wallclock secs (14.10 usr + 0.00 sys = 14.10 CPU) @ 354.61/s (n=5000) naive: 0 wallclock secs ( 0.04 usr + 0.00 sys = 0.04 CPU) @ 125000.00/s (n=5000) orcish: 1 wallclock secs ( 0.04 usr + 0.00 sys = 0.04 CPU) @ 125000.00/s (n=5000) schwartzian: 26 wallclock secs (25.70 usr + 0.03 sys = 25.73 CPU) @ 194.33/s (n=5000)