|laziness, impatience, and hubris|
without other details (it's the data already in memory?) it's a matter of guessing, but..
pass by reference? Are you filling new datastructures to pass your data around? If the original data it's alreaady read you can take a reference to some items and pass just the reference to your subroutines. See also the same matter at effective perl programmer and Is it possible to do pass by reference in Perl?
This big amount of data and relations between parts let me think of databases: you can have a first step where you put all your data into a (temporary?) database (sqlite for example) and a second step where you just SELECT appropriate items and you update your statistics.
Be sure of freeing no more used variables. Four days for just 2 millions records seems a bit slow for me.
If my suggestions do not fit your task please provide a bit more details.
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.