科技小数据 Arrow:使用零内存读取DataFrame,Apache( 三 )


阅读时间
现在的关键部分:阅读性能 。 计算平均长度需要多长时间?
·CSV
·Parquet
【科技小数据 Arrow:使用零内存读取DataFrame,Apache】·带有文件API的Arrow(OSFile(…))
·带有缺失值/NaN的Arrow作为内存映射API(memory_map(…))
·Arrow作为内存映射API(memory_map(…)) , 没有缺少值
对这三个功能中的每一个进行计时 , 会产生以下结果:
科技小数据 Arrow:使用零内存读取DataFrame,Apache
文章图片
>Performancecomparison:Timerequiredtoreadcolumn&calculateaverage
毫不奇怪 , csv是最慢的选择 。 它要求读取200MB , 解析文本 , 丢弃除长度以外的所有列 , 然后计算平均值 。
由于不需要解析整个文件 , 因此Parquet的速度提高了约60倍-仅读入了所需的列 。
缺少值的Arrow比Parquet快约3倍 , 比csv快约200倍 。 与Parquet一样 , Arrow可以将自身限制为仅读取指定的列 。 使速度更快的原因是无需解压缩列 。
请注意 , 使用零复制和不使用零复制来读取内存映射的Arrow文件之间的差异意味着性能又提高了约3倍(即零复制的总速度比csv快600倍 , 比Parquet快9倍) 。
令人惊讶的是:带有文件API的Arrow甚至比Parquet慢 。 这是怎么回事?
内存消耗
为了回答这个问题 , 让我们看一下内存消耗 。 如果我们只读一列 , 每个文件消耗多少RAM?
结果如下:
科技小数据 Arrow:使用零内存读取DataFrame,Apache
文章图片
>Performancecomparison:Memoryconsumedtoreadcolumn
最值得注意的是:带有文件API的Arrow占用189MB的空间-几乎是整个文件的大小(即使我们只读取一列?!) 。 答案在于文档:
"[…]OSFile在每次读取时分配新的内存 , 就像Python文件对象一样 。 "[3]
通过使用OSFile , 整个文件首先被读取到内存中 。 现在显而易见 , 为什么此操作要比Parquet慢并且占用最多的内存!
但是 , 通过使用内存映射功能和填充的NaN值 , 可直接在存储的Arrow文件顶部创建pandasDataFrame 。 没有复制:0MB的RAM!毫不奇怪 , 这是最快的选择 。
您可以在这里找到整个JupyterNotebook
结论
对我来说 , 有很多关于Arrow的知识 。 到目前为止 , 我了解到的是:您也不能吃蛋糕也不能吃它 。 在[7]之间需要权衡:
·优化磁盘空间/在磁盘上长期存储→Parquet
·优化数据交换和快速检索→Arrow
与csv相比 , Parquet和Arrow的性能提升都非常显着 。 当将Arrow存储到磁盘时 , 它消耗的存储空间比Parquet更多 。 但是 , 在读取性能方面 , Avro在时间和内存消耗方面都超过了Parquet 。 所提供的示例(计算一列/读取列的平均值)只是表面上的划痕-我的期望是 , 随着查询的复杂度和数据集的增加 , Arrow会更加发光 。
只要使用内存映射功能读取Arrow , 读取性能就令人难以置信 。 最好的情况是数据集没有缺失值/NaN 。 然后 , PyArrow可以发挥其神奇作用 , 并允许您在表上进行操作 , 而几乎不占用任何内存 。
未来的确已经来了-真是太神奇了!


推荐阅读