HDF5 - 并发,压缩和I/O性能

Ame*_*ina 64 python sqlite hdf5 pandas

我有关于HDF5性能和并发性的以下问题:

  1. HDF5是否支持并发写访问?
  2. 除了并发性考虑外,HDF5在I/O性能方面的表现如何(压缩率是否会影响性能)?
  3. 由于我在Python中使用HDF5,它的性能与Sqlite相比如何?

参考文献:

Jef*_*eff 76

更新为使用pandas 0.13.1

1)编号http://pandas.pydata.org/pandas-docs/dev/io.html#notes-caveats.有多种方法可以做到这一点,例如让不同的线程/进程写出计算结果,然后将一个进程组合​​起来.

2)根据您存储的数据类型,操作方式以及检索方式,HDF5可以提供更好的性能.在存储HDFStore作为一个单一的阵列,浮点数据,压缩的(换句话说,不将其存储在格式,允许用于查询),将被存储/读取惊人快.即使以表格格式存储(这会降低写入性能),也会提供相当好的写入性能.您可以查看一下这些详细的比较(这是HDFStore在引擎盖下使用的).http://www.pytables.org/,这是一张很好的照片:

(因为PyTables 2.3的查询现在被编入索引),所以perf实际上要比这更好.所以回答你的问题,如果你想要任何类型的性能,HDF5是要走的路.

写作:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这是代码

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')
Run Code Online (Sandbox Code Playgroud)

当然是YMMV.

  • 这些sqlite时间是错误的:打开和关闭连接通常不会在每个查询中完成,并且不应该是所测时间的一部分。(更不用说系统调用来检查是否存在并删除先前的sqlite文件)。这样可能对timeit友好,但这是不正确的。 (3认同)
  • 另外,有人可能会说,将sqlite与hdf5进行公平的比较不是将其转储到BLOB中,而是转储到了“标准”表中。Sqlite实际上非常好,并且在读写二进制数据方面通常优于HDF5。 (3认同)