Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Array of Hashes vs. Array of Arrays vs Array of Lines vs ...

by Anonymous Monk
on Aug 30, 2007 at 14:24 UTC ( [id://636092]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I have to read in some CSV data from a flat data file, something like:
1.1,2.1,3.7 .... 1.4,4.4,2.2 . . .

(many columns and many more rows than columns)
The file has many columns and rows and is approximately 1gb in size. Each column has a different meaning. I am looking for the best way to keep the file in memory. At this time I have come up with the following:

Array of hashes: This way mimicks an array of struct in C e.g., $z = $Data[$RecNo]{'Intensity'}; . I have heard that keeping many small hashes around is wasteful, however. And, given the regularity of the data, this seems sub-optimal.

Hash of arrays: This way is backways from the Array of Hashes, but only uses as many hash entries as there are columns. $z = $Data{'Intensity'}[$RecNo];

use constant INTENSITY => 2;

Array of small arrays: $z = $Data[$RecNo][INTENSITY];

Small array of large arrays: $z = $Data[INTENSITY]; <br>[$RecNo];

Alternative, I can keep each line in memory and split the line at the time of access (this means that scalars will hold larger chunks).

Is there any sense of which of these methods are 'best' somehow? Any help would be appreciated.

(Also, how much memory do small scalars take? A small array? Any help from someone with Devel::Size would be appreciated!)

Replies are listed 'Best First'.
Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by BrowserUk (Patriarch) on Aug 30, 2007 at 15:22 UTC

    Update:ysth just pointed out that your example data isn't two lines of 6 comma-separated single digits, but rather 2 x 3 comma-separated small floats.

    That doesn't change the possibility of using packed array for you data, but it restrict the choices of available package that may be applicable. It could also double the storage requirement if you need the accuracy.

    It also make using PDL perhaps the better choice depending on how you are going to manipulate the data. It carries the burden of being a pain to install, stupid notation, weird restrictions, huge learning curve and dog-aweful documentation--but it is both memory efficient and fast.


    The most memory efficient method would be to used a tied array of packed integers or shorts. Each line of your file will require a single scalar, and each value 2 or 4 bytes depending upon the range of your values. As your original file is ascii encoded and contains lots of commas, the resultant memory structure might actually require less space that the file does on disk.

    There are several packages on cpan for this: Packed::Array if you need the full 32-bit range for your values, or Tie::Array::packedC which appears to handle different size values, or Tie::IntegerArray and others.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by ysth (Canon) on Aug 30, 2007 at 14:51 UTC
    How long are your lines? How many columns are there on average? Is the data all real numbers? If so, to what precision and with what range of values? If not, what else is there? How much memory do you have to spare? Why do you want to keep it in memory? How will you be accessing it?

    My immediate reaction is to say anything other than a simple array of strings (lines) is likely to take many gigabytes.

    Size of scalars varies depending on contents and your perl configuration. In general, references or integers (that have never been used in string context) will take the least amount of memory. Floating point numbers take more. Strings take more than that. Mixed strings/numbers (including numbers that have been used in a string context, so have the string representation cached) even more.

Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by andyford (Curate) on Aug 30, 2007 at 14:35 UTC

    I would think that "keeping it in memory" would be dependent on how much memory you have. If you have plenty, then perl will have no problem reading in the whole file and you should use whatever data structure fits how you're gonna use it. If you don't have enough memory you could try Tie::File to effortlessly access the lines while leaving the data on disk. Trying to optimize via different data structures is probably a waste of time and also probably counter productive.

    non-Perl: Andy Ford

Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by moritz (Cardinal) on Aug 30, 2007 at 15:00 UTC
    It all depends on what you want to do with the values, though I guess an AoA is faster and more memory efficient than a AoH.

    Again depending on what you want to do with it, perhaps DBI and DBD::CSV might help you.

Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by Anno (Deacon) on Aug 30, 2007 at 15:54 UTC
    Another possibility: PDL. It combines compact storage with sophisticated access methods.

    Anno

Re: Array of Hashes vs. Array of Arrays vs Array of Lines vs ...
by GrandFather (Saint) on Aug 30, 2007 at 21:26 UTC

    Why do you need to "keep the file in memory"? You may be better to use DBI and DBD::AnyData and treat your file as a database.


    DWIM is Perl's answer to Gödel

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://636092]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-19 14:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found