in reply to What are the other option for sorting the keys of hash of hashes

Your question is very ambiguous. What problem are you trying to fix?
  • Comment on Re: What are the other option for sorting the keys of hash of hashes

Replies are listed 'Best First'.
Re^2: What are the other option for sorting the keys of hash of hashes
by salva (Canon) on Sep 29, 2008 at 11:38 UTC
Re^2: What are the other option for sorting the keys of hash of hashes
by luckypower (Beadle) on Sep 29, 2008 at 11:24 UTC
    my @sort = sort {$hash{$a}->{"Size"} <=> $hash{$b}->{"Size"}} keys %hash;
    i think to sort keys of hash which contains another hashes using this way is very costly.

    so want to know is there any other option to do so..???
      Do you have actual performance problems? If not, don't worry about it. And if you have performance problems, profile your code first to find out which parts of the code consume the most time.

      In case of many items the hash lookups can be reduced with a Schwartzian Transform, but it will eat more memory in turn, and likely to only give you a small speedup, if any.

        moritz, i dont have any performance problem....
        This is just for knowledge....
        thanks

      No, this is quite efficient. Hash accesses are very fast.

      But if you really think you need every cycle, you might try the following

      use warnings; use strict; my %hash= ('a' => {'Size' => 40 }, 'b' => {'Size' => 3000 }, 'c' => {'Size' => 20 }, 'd' => {'Size' => 1 }, 'e' => {'Size' => 12 } ); my @unsort= map ( $hash{$_}->{"Size"} .':' . $_ , keys %hash); no warnings; my @sort= sort {$a<=>$b } @unsort; use warnings; foreach (@sort) { s/[^:]*://; } print join' ',@sort,"\n"; # prints d e c a b

      You really should test whether you get any speedup through this, you need fairly large hashes to see any difference at all, as you trade two hash accesses for two string-to-int conversions per sort operation. I'm not sure what will win

      Instead of turning off the warnings you could also normalize the size numbers for the sorting by putting '0' before each number so that all numbers are the same size and extract the numbers in the sort routine, but that will definitely eat up any speedup over your original sort

      UDPATE: Yes, forgot the Schwarzian Transform, again.
        No, this is quite efficient. Hash accesses are very fast ... You really should test whether you get any speedup through this

        Here is some benchmark code that explores this.

        The output.

        Rate Simple ClassicST Jethro ClassicGRT Simple 11.3/s -- -13% -46% -55% ClassicST 13.0/s 16% -- -37% -48% Jethro 20.8/s 84% 59% -- -17% ClassicGRT 25.0/s 122% 92% 20% --

        Your sorting code is a bit odd in that it appears to be a halfway house between a ST and a GRT. It has some issues with "numeric" warnings and a reliance on Perl doing the right thing (which is does at the moment but perhaps that might change) when doing a numerical sort on non-numerical strings that happen to have leading digits. It is pretty quick though, only beaten by the GRT. I have altered your code a bit by using simple interpolation in the map instead of concatenation and by localising and better targetting the no warnings instruction.

        The usual caveats apply regarding my benchmarks. I've cocked them up before and I'm sure I will again.

        Cheers,

        JohnGG

        Update: Corrected typo, s/you/your/