Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

random behaviour of perl hashes

by evilgoblin (Novice)
on Aug 28, 2006 at 00:08 UTC ( [id://569904]=perlquestion: print w/replies, xml ) Need Help??

evilgoblin has asked for the wisdom of the Perl Monks concerning the following question:

Given a hash having the exact same key value pairs is the list given by 'keys %hash' the same? for example in this program
%hash = ( '1' => 'one', '2' => 'two', '3' => 'three',); for $key (keys %hash) { print "$key\n"; }
is the output the same every time the program is run Or is there a possibility of the output being different (basically is there a random component, every time the program is run, to the ordering of the hash keys given that the key and the values stay the same).

Replies are listed 'Best First'.
Re: random behaviour of perl hashes
by lima1 (Curate) on Aug 28, 2006 at 00:16 UTC
    from keys:

    The keys are returned in an apparently random order. The actual random order is subject to change in future versions of perl, but it is guaranteed to be the same order as either the "values" or "each" function produces (given that the hash has not been modified). Since Perl 5.8.1 the ordering is different even between different runs of Perl for security reasons (see "Algorithmic Complexity Attacks" in perlsec).

Re: random behaviour of perl hashes
by Tanktalus (Canon) on Aug 28, 2006 at 00:39 UTC

    Generally speaking, even if Perl were to give you the same output each time, I doubt it would be sage advice to count on what that order was in any way. Merely upgrading perl could give you a different set of answers (if Perl-5-Porters were to suddenly find a new magical algorithm that solved some issue of speed, memory, or both, for example). Which means that if you moved from one machine (running Perl 5.8.1) to another (running Perl 5.8.3, say), you could get different answers.

    Thus, the answer has always been that if you need some sort of order to these keys, you need to impose that order yourself (via sort or Tie::IxHash or something). As lima1 says, they now force this good habit on you to reduce security exposure risks. But that doesn't change the fact that it was always a good idea.

      ah but this thread suggests differently atleast for 'small' hashes. By small I mean with less than 20 keys in a bucket.

      Edit g0n: converted href to pm link

Re: random behaviour of perl hashes
by blue_cowdawg (Monsignor) on Aug 28, 2006 at 02:19 UTC
        basically is there a random component, every time the program is run, to the ordering of the hash keys given that the key and the values stay the same

    I'm a firm believer in doing empirical testing so I wrote a little sniglet of code:

    #!/usr/bin/perl -w use strict; use Data::Dumper; my @ingredients = ( [ qw / onions diced / ], [ qw / potatos diced / ], [ qw / paprika spicy / ], [ qw / salt shaken / ], [ qw / pepper fresh / ] ); my $hash_browns={}; foreach my $ingredient (@ingredients){ $hash_browns -> { $ingredient -> [0] } = $ingredient -> [1]; } foreach my $key ( keys %$hash_browns ){ printf "%s\t%s\n",$key,$hash_browns->{$key}; }

    When I run this code three times I get something like this:

    [pberghol@cowdawg hash]$ perl hash.pl salt shaken onions diced pepper fresh paprika spicy potatos diced [pberghol@cowdawg hash]$ perl hash.pl salt shaken onions diced pepper fresh paprika spicy potatos diced [pberghol@cowdawg hash]$ perl hash.pl salt shaken onions diced pepper fresh paprika spicy potatos diced
    Looks pretty much the same to me.

    Now, I'm not sure why this is all important, but if I were looking for random behavior, I'd program for it and not count on a "freak of nature" in my programming language of choice to give it to me. On the other hand if predictable behavior is what I want, again I'll program for that.


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

      As lima1 pointed out this behaviour has been deliberately changed as of the perl 5.8.*, I get this with 5.8.1:

      [jonathan@orpheus jonathan]$ perl foo.pl potatos diced pepper fresh salt shaken paprika spicy onions diced [jonathan@orpheus jonathan]$ perl foo.pl pepper fresh potatos diced onions diced paprika spicy salt shaken [jonathan@orpheus jonathan]$ perl foo.pl salt shaken paprika spicy onions diced potatos diced pepper fresh
      but yes it would be a mistake to rely on an any hash ordering behaviour in a programme.

      /J\

        I get this running ActiveState's 5.8.8 (build 817):

        Case 1 salt shaken onions diced pepper fresh paprika spicy potatos diced Case 2 salt shaken onions diced pepper fresh paprika spicy potatos diced Case 3 salt shaken onions diced pepper fresh paprika spicy potatos diced

        I suspect that it has to do with the details of the implementation of the hashing algorithm, which may differ from system to system.

        My interpretation of the "random ordering" in the perldocs is simply that "we refuse to guarantee the order of the keys for a hash".

        emc

        Only two things are infinite, the universe and human stupidity, and I'm not sure about the former.

        Albert Einstein
Re: random behaviour of perl hashes
by Joost (Canon) on Aug 28, 2006 at 21:39 UTC
      i.e. running a perl program twice will probly not give the same order.

      s/probly not/almost always/, actually. But the "almost" is the important part. (: Don't rely on the order not changing, but you'll be even more disappointed if you try to rely on the order not staying the same.

      - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://569904]
Approved by BrowserUk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-19 09:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found