in reply to Weighted random selection

Doesn't really address your overall efficiency question, but I see over and over people forgetting (or never having known) that push takes a LIST, not just a single scalar:
while ( $group->{$advert} > 0 ) { push( @rndselect, $advert ); $group->{$advert}--; }#while
becomes
push( @rndselect, ($advert) x $group->{$advert} );