【问题标题】:HDF5 - concurrency, compression & I/O performance [closed]HDF5 - 并发、压缩和 I/O 性能 [关闭]
【发布时间】:2013-05-13 18:14:46
【问题描述】:

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

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

参考资料:

【问题讨论】:

  • 我认为这个问题可能不是建设性的而不是离题,但我想不出应该如何措辞才能成为话题(我试过并放弃了)。如果进行调整,将很乐意投票重新开放并投票。

标签: python sqlite pandas hdf5


【解决方案1】:

更新为使用 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

阅读

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

这是代码

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')

当然是 YMMV。

【讨论】:

  • 您使用的是哪个 RDBMS?该图指示 PostgreSQL,但代码显示 sqlite3。
  • 时间来自本地 sqlite 基于文件(包含在 python 中)。该情节是由PyTables 人原创的,我认为使用了postgresql(这是一项真正的研究,非常详细)。
  • 那些 sqlite 计时是错误的:打开和关闭连接通常不会在每次查询时完成,也不应该是测量时间的一部分。 (更不用说系统调用来检查是否存在并删除以前的 sqlite 文件)。这样可能是timeit-friendly,但它是不正确的。
  • 另外,有人可能会争辩说,将 sqlite 与 hdf5 进行公平(呃)比较并没有倾倒到 BLOBs 而不是“标准”表中。 Sqlite 实际上相当不错,而且在读写二进制数据方面通常比 HDF5 更好。
  • 其他模式也在同一个函数调用中处理连接打开和关闭;再加上像我这样的用例(被动服务器等待来自多个用户的请求),sqlite 不会永远保持“连接”状态,无论如何都必须连接和关闭每个函数调用。所以恕我直言,这种比较对于必须发生一次性操作的用例来说是正确的。希望看到更多这样的基准测试。
【解决方案2】:

看看pytables,他们可能已经为你做了很多这样的工作。

也就是说,我并不完全清楚如何比较 hdf 和 sqlite。 hdf 是通用分层数据文件格式 + 库,sqlite 是关系数据库。

hdf 确实支持 c 级别的并行 I/O,但我不确定 h5py 包含多少,或者它是否可以与 NFS 配合使用。

如果您真的想要一个高度并发的关系数据库,为什么不直接使用真正的 SQL 服务器?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2013-06-15
    • 2021-11-25
    • 2012-08-06
    相关资源
    最近更新 更多