Getting back to your basic question: Can you avoid hash preallocation? Well, not really ... the hash has to be allocated to something. But you can allocate your own buckets by assigning to the keys function like this:
keys(%hash) = 512;
There are caveats -- Perl will round up to a power of 2 if needed.
As far as I know, Perl maintains the initial hash allocation and does not reallocate along the way, but I may be wrong about that.
There is no way to really use "just what you need" in a hash as you suggest ... The design of a hash guarantees that there will almost always be some unused slots unless you have a perfect hashing algorithm. That would be called an array. 8-)