Re: Pick any key from a very large hash
by mzedeler (Pilgrim) on Jul 11, 2009 at 21:55 UTC
|
| [reply] [d/l] |
|
| [reply] |
Re: Pick any key from a very large hash
by jwkrahn (Abbot) on Jul 11, 2009 at 22:23 UTC
|
| [reply] |
|
| [reply] [d/l] [select] |
|
"In particular, calling keys() in void context resets the iterator with no other overhead."
| [reply] |
|
|
| [reply] |
|
| [reply] |
|
Calling keys in void context resets the iterator and does nothing else. The number of keys in the hash is of no import.
| [reply] [d/l] |
|
Re: Pick any key from a very large hash
by Bloodnok (Vicar) on Jul 11, 2009 at 22:26 UTC
|
...each is meant for looping through the entire hash... - you're dead right - the hash is meant to be invariant over each - from each '...If you add or delete elements of a hash while you're iterating over it, you may get entries skipped or duplicated, so don't...'.
In answer to your question, again from each - '..it can be reset by reading all the elements from the hash, or by evaluating keys HASH or values HASH...'.
The moral of the story/posting is ... please RTFM before you post.
A user level that continues to overstate my experience :-))
| [reply] [d/l] [select] |
|
| [reply] |
|
use strict;
use warnings;
use Benchmark qw(cmpthese);
my %bigHash = map {$_ => undef} 1 .. 1e3;
my @resetEach = keys %bigHash;
my ($key) = each %bigHash;
my $count = keys %bigHash;
my ($key2) = each %bigHash;
print "First key '$key', second '$key2'\n";
cmpthese (
-1,
{
scalarKeys => sub {scalar keys %bigHash},
listKeys => sub {() = keys %bigHash},
}
);
Prints:
First key '559', second '559'
Rate listKeys scalarKeys
listKeys 5184/s -- -100%
scalarKeys 15969899/s 307964% --
True laziness is hard work
| [reply] [d/l] [select] |
|
Re: Pick any key from a very large hash
by ashish.kvarma (Monk) on Jul 12, 2009 at 04:28 UTC
|
If you don’t want to use "keys", here is a fancy way to do it.
my %hash = (
a => 1,
b => 2,
c => 3,
d => 4,
e => 5,
f => 6,
g => 7,
h => 8,
i => 9,
j => 10,
);
my $hash_length = %hash;
# To get actual length you would need 'scalar keys %hash'
# But we are not using 'keys' here so lets get the length other way
$hash_length =~ s{/.*}{};
foreach (1...10) {
my $rand_num = rand $hash_length;
# Make sure number is even.
$rand_num = ($rand_num %2) ? ($rand_num - 1) : ($rand_num);
my $key = (%hash)[$rand_num];
print "$_\t: $key\n";
}
# output
# 1 : e
# 2 : d
# 3 : c
# 4 : j
# 5 : a
# 6 : e
# 7 : e
# 8 : c
# 9 : j
# 10 : e
| [reply] [d/l] |
|
use strict;
use warnings;
use Benchmark qw(cmpthese);
my %bigHash = map {$_ => undef} 1 .. 1e3;
my ($key) = each %bigHash;
my $count = keys %bigHash;
my ($key2) = (%bigHash)[0];
print "First key '$key', second '$key2'\n";
cmpthese (
-1,
{
byEach => sub {scalar keys %bigHash; my ($key) = each %bigHas
+h;},
byArray => sub {my $key = (%bigHash)[0]},
}
);
Prints:
First key '559', second '559'
Rate byArray byEach
byArray 5228/s -- -100%
byEach 2414187/s 46082% --
It's that 'temporary array' OP was worried about. A fancy solution no doubt but, for saving time, not a good one.
True laziness is hard work
| [reply] [d/l] [select] |
|
I jumped in without giving it a thought and missed the real problem. I do agree it wouldn’t be efficient therefore won’t solve the purpose.
I guess I gotta give some time before jumping in.
| [reply] |
|
| [reply] |
Re: Pick any key from a very large hash
by psini (Deacon) on Jul 11, 2009 at 22:01 UTC
|
Can't you simply exit from the each when you are done, and maybe include it in an external loop of some kind?
Or have I completely missed the point?
Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."
| [reply] [d/l] [select] |
|
I tried using each without looping at all, which caused weird results when arbitrary pairs were added or deleted between each each.
exit would be taking things a bit too far, perhaps you meant last? :-) Alternatively, if you mean use a separate process, this would defeat the DB_File built-in cache and generally kill performance.
OR maybe I'm the one missing the point...
--
Time flies when you don't know what you're doing
| [reply] [d/l] [select] |