Perl: Any quick way to use regex on hash keys?

Hi,

Is there any quick way to use pull out keys that match a specific regex pattern?

eg

%hash ;
$hash(123,456) = xxx;
$hash(123,457) = xxx;
$hash(123,458) = xxx;
$hash(223,459) = xxx;

I need a fast way to get all the keys that start with 123..
Meaning I should get

$hash(123,456) = xxx;
$hash(123,457) = xxx;
$hash(123,458) = xxx;

only....

Currently I am looking through all the keys and using regex on them. I have over 2k such keys and it is making my program very slow. I am trying to tune it. Any suggestions are welcomed. Thank you.

Can you post your code that does this ?

tyler_durden

Here is the code...

 foreach $errBillkey(keys %hash)
 {
         if($errBillkey =~ m/^$account_no,.*/ )
        {
              // do something here
       }
}


That looks quite okay. I tested out a similar logic with 7000 keys, and the time taken to create the hash + match + print is less than 1 second.

$ time perl -le 'BEGIN{$p="123"} foreach (120000..127000){$x{$_} = "xyz"} foreach $k(keys %x){if ($k =~ m/^$p.*/){print $k}}'
123223
123696
123691
...
...
123322
123712
123719

real    0m0.106s
user    0m0.048s
sys    0m0.019s
$

Maybe the bulk of the time is spent in the "do something" part ?

tyler_durden

This could be a bit faster:

foreach $errBillkey(grep { /^$account_no/} keys %hash)

Unless you have to, don't try to match beyond the criteria. If it's still slow, you might want break down the hash a bit more, eg by creating a hash of hashes, where the keys of the first hash are the digits left of the comma.

Thanks pludi and durden_tyler for helping to look at my issue.
I think the issue has been settled with pludi's suggestion. I will look into changing the code with hash of hash when i have time :slight_smile: