in reply to Re^2: Hash sorting (by value) woes
in thread Hash sorting (by value) woes

Here's an optmization that only executes the regexp once per string:

@sorted_keys = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { $etcpw->{$_} =~ /:(\d+)/; [ $_, $1 ] } keys %{$etcpw}; print "$etcpw->{$_}\n" foreach @sorted_keys;

We can even drop a step:

print "$etcpw->{$_->[0]}\n" foreach sort { $a->[1] <=> $b->[1] } map { $etcpw->{$_} =~ /:(\d+)/; [ $_, $1 ] } keys %{$etcpw};

Replies are listed 'Best First'.
Re^4: Hash sorting (by value) woes
by Roy Johnson (Monsignor) on Feb 24, 2005 at 17:33 UTC
    Of course, if you really want to use map instead of foreach:
    print map {"$etcpw->{$_}\n"} sort { $a->[1] <=> $b->[1] } map { $etcpw->{$_} =~ /:(\d+)/; [ $_, $1 ] } keys %{$etcpw};

    Caution: Contents may have been coded under pressure.

      True, but it would be slower.

      print map { ...1... } ...2...;

      is closer to

      @temp_list = map { ...1... } ...2...; print @temp_list;

      than to

      print ...1... foreach ...2...;

      The extra assignment slows things down. (About twice as slow, IIRC previous tests.)

      Update: Fixed brain fart R.J. noticed.

        Isn't it more like
        @temp_list = map { ...1... } ...2....; print @temp_list;
        ? The map is done before print sees it, and print is only called once, with a list. It is slower, of course, because you do have an extra list-building step. Interestingly, it is not slower than map in a void context (I'm using 5.8.0 here -- when was that optimized?):
        use Benchmark 'cmpthese'; my @vals = (10_000..15_000); open(ABYSS, '>', '/dev/null') or die "The abyss is closed.\n"; cmpthese(-2, { 'map' => sub { print ABYSS map {">>$_<<\n"} @vals }, 'map_void' => sub { map {print ABYSS ">>$_<<\n"} @vals }, 'for' => sub { print ABYSS ">>$_<<\n" for @vals } }); close ABYSS; __END__ Rate map_void map for map_void 11.9/s -- -23% -50% map 15.5/s 30% -- -34% for 23.6/s 99% 52% --

        Caution: Contents may have been coded under pressure.