9

我正在使用pythons bz2模块生成(并压缩)一个大型 jsonl 文件(bzip2 压缩 17GB)。

但是,当我后来尝试使用 pbzip2 对其进行解压缩时,它似乎只使用一个CPU 内核进行解压缩,这很慢。

当我用 pbzip2 压缩它时,它可以利用多个核心进行解压缩。有没有办法在 python 中以 pbzip2 兼容的格式压缩?

import bz2,sys
from Queue import Empty
#...
compressor = bz2.BZ2Compressor(9)
f = open(path, 'a')

    try:
        while 1:
            m = queue.get(True, 1*60)
            f.write(compressor.compress(m+"\n"))
    except Empty, e:
        pass
    except Exception as e:
        traceback.print_exc()
    finally:
        sys.stderr.write("flushing")
        f.write(compressor.flush())
        f.close()
4

2 回答 2

4

一个pbzip2流只不过是多个bzip2流的串联。

使用外壳的示例:

bzip2 < /usr/share/dict/words > words_x_1.bz2
cat words_x_1.bz2{,,,,,,,,,} > words_x_10.bz2
time bzip2 -d < words_x_10.bz2 > /dev/null
time pbzip2 -d < words_x_10.bz2 > /dev/null

我从来没有使用过python的bz2模块,但是应该很容易以'a'附加模式关闭/重新打开一个流,每隔这么多字节,以获得相同的结果。请注意,如果BZ2File是从现有的类文件对象构造的,则关闭BZ2File不会关闭底层流(这是您想要的)。

我还没有测量多少字节最适合分块,但我猜每 1-20 兆字节 - 它肯定需要大于 bzip2 块大小(900k)。

另请注意,如果您记录每个块的压缩和未压缩偏移量,则可以进行相当有效的随机访问。这就是dictzip程序的工作方式,尽管它基于gzip.

于 2017-09-19T19:25:10.967 回答
1

如果您绝对必须pbzip2在解压缩时使用,这对您没有帮助,但替代方法lbzip2可以执行“普通”.bz2文件的多核解压缩,例如由 PythonBZ2File或传统bzip2命令生成的文件。这避免了pbzip2您所描述的限制,如果文件也使用pbzip2. 请参阅https://lbzip2.org/

作为奖励,基准测试表明在解压缩(30%)和压缩(40%)方面lbzip2都比 快得多pbzip2,同时实现略优的压缩比。此外,它的峰值 RAM 使用量不到pbzip2. 请参阅https://vbtechsupport.com/1614/

于 2019-10-31T19:59:22.330 回答