it-swarm.com.de

HDF5 - Parallelität, Komprimierung und E / A-Leistung

Ich habe die folgenden Fragen zur Leistung und Parallelität von HDF5:

  1. Unterstützt HDF5 gleichzeitigen Schreibzugriff?
  2. Abgesehen von Nebenläufigkeitsüberlegungen, wie ist die HDF5-Leistung in Bezug auf die E/A-Leistung (wirkt sich die Komprimierungsrate auf die Leistung aus)?
  3. Wie ist die Leistung von HDF5 mit Sqlite, da ich es mit Python verwende?

Verweise:

63

Aktualisiert, um pandas 0.13.1 zu verwenden

1) Nein. http://pandas.pydata.org/pandas-docs/dev/io.html#notes-caveats . Es gibt verschiedene Möglichkeiten, dies zu tun , z.B. Lassen Sie Ihre verschiedenen Threads/Prozesse die Berechnungsergebnisse ausschreiben und dann einen einzelnen Prozess kombinieren.

2) Je nachdem, welche Art von Daten Sie speichern, wie Sie sie speichern und wie Sie sie abrufen möchten, kann HDF5 eine erheblich bessere Leistung bieten. Das Speichern in einem HDFStore als einzelnes Array, Float-Daten, die komprimiert (dh nicht in einem abfragbaren Format gespeichert) sind, werden erstaunlich schnell gespeichert/gelesen. Selbst das Speichern im Tabellenformat (das die Schreibleistung verlangsamt) bietet eine recht gute Schreibleistung. Sie können sich dies für einige detaillierte Vergleiche ansehen (was HDFStore unter der Haube verwendet). http://www.pytables.org/ , hier ist ein schönes Bild: 

(und seit PyTables 2.3 sind die Abfragen jetzt indiziert), also ist perf tatsächlich VIEL besser als dieses. Um Ihre Frage zu beantworten, wenn Sie irgendeine Art von Leistung wünschen, ist HDF5 der richtige Weg.

Schreiben:

In [14]: %timeit test_sql_write(df)
1 loops, best of 3: 6.24 s per loop

In [15]: %timeit test_hdf_fixed_write(df)
1 loops, best of 3: 237 ms per loop

In [16]: %timeit test_hdf_table_write(df)
1 loops, best of 3: 901 ms per loop

In [17]: %timeit test_csv_write(df)
1 loops, best of 3: 3.44 s per loop

Lesen

In [18]: %timeit test_sql_read()
1 loops, best of 3: 766 ms per loop

In [19]: %timeit test_hdf_fixed_read()
10 loops, best of 3: 19.1 ms per loop

In [20]: %timeit test_hdf_table_read()
10 loops, best of 3: 39 ms per loop

In [22]: %timeit test_csv_read()
1 loops, best of 3: 620 ms per loop

Und hier ist der Code

import sqlite3
import os
from pandas.io import sql

In [3]: df = DataFrame(randn(1000000,2),columns=list('AB'))
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Data columns (total 2 columns):
A    1000000  non-null values
B    1000000  non-null values
dtypes: float64(2)

def test_sql_write(df):
    if os.path.exists('test.sql'):
        os.remove('test.sql')
    sql_db = sqlite3.connect('test.sql')
    sql.write_frame(df, name='test_table', con=sql_db)
    sql_db.close()

def test_sql_read():
    sql_db = sqlite3.connect('test.sql')
    sql.read_frame("select * from test_table", sql_db)
    sql_db.close()

def test_hdf_fixed_write(df):
    df.to_hdf('test_fixed.hdf','test',mode='w')

def test_csv_read():
    pd.read_csv('test.csv',index_col=0)

def test_csv_write(df):
    df.to_csv('test.csv',mode='w')    

def test_hdf_fixed_read():
    pd.read_hdf('test_fixed.hdf','test')

def test_hdf_table_write(df):
    df.to_hdf('test_table.hdf','test',format='table',mode='w')

def test_hdf_table_read():
    pd.read_hdf('test_table.hdf','test')

Natürlich YMMV.

76
Jeff

Schauen Sie sich pytables an, sie haben möglicherweise bereits viel für Sie erledigt.

Trotzdem ist mir nicht ganz klar, wie man hdf und sqlite vergleicht. hdf ist ein hierarchisches Allzweck-Datendateiformat + Bibliotheken und sqlite ist eine relationale Datenbank.

hdf unterstützt parallele E/A auf der Ebene c, aber ich bin nicht sicher, wie viel davon h5py wraps oder ob es Nizza mit NFS spielen wird.

Wenn Sie wirklich eine hochgradig parallele relationale Datenbank möchten, warum nicht einfach einen echten SQL-Server verwenden?

2
tacaswell