是否可以并行化 bz2 的解压?
Is it possible to parallelize bz2's decompression?
我正在使用 pythons bz2 模块生成(并压缩)一个大的 jsonl 文件(bzip2 压缩后 17GB)。
不过后来我用pbzip2解压的时候好像只用了one CPU-core解压,速度很慢
当我用 pbzip2 压缩它时,它可以在解压缩时利用多个内核。有没有办法以 pbzip2 兼容格式在 python 内进行压缩?
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()
一个pbzip2
流只不过是多个bzip2
流的串联。
使用 shell 的示例:
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'
ppend模式下close/reopen一个流应该很容易,每隔这么多字节,以获得相同的结果。请注意,如果 BZ2File
是从现有的类似文件的对象构造的,则关闭 BZ2File
不会关闭基础流(这就是您在这里想要的)。
我没有测量多少字节最适合分块,但我猜每 1-20 兆字节 - 它肯定需要大于 bzip2 块大小 (900k)。
另请注意,如果记录每个块的压缩和未压缩偏移量,则可以进行相当高效的随机访问。这就是 dictzip
程序的工作方式,尽管它基于 gzip
.
如果你绝对必须在解压时使用pbzip2
这对你没有帮助,但替代lbzip2
可以执行"normal" .bz2
文件的多核解压,例如与 Python 的 BZ2File
或传统的 bzip2
命令生成的一样。这避免了您描述的 pbzip2
的限制,如果文件也使用 pbzip2
压缩,它只能实现并行解压缩。参见 https://lbzip2.org/。
作为奖励,基准测试表明 lbzip2
在解压缩(30%)和压缩(40%)方面比 pbzip2
快得多,同时实现了略微优越的压缩率。此外,它的 RAM 使用峰值不到 pbzip2
使用的 RAM 的 50%。参见 https://vbtechsupport.com/1614/。
我正在使用 pythons bz2 模块生成(并压缩)一个大的 jsonl 文件(bzip2 压缩后 17GB)。
不过后来我用pbzip2解压的时候好像只用了one CPU-core解压,速度很慢
当我用 pbzip2 压缩它时,它可以在解压缩时利用多个内核。有没有办法以 pbzip2 兼容格式在 python 内进行压缩?
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()
一个pbzip2
流只不过是多个bzip2
流的串联。
使用 shell 的示例:
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'
ppend模式下close/reopen一个流应该很容易,每隔这么多字节,以获得相同的结果。请注意,如果 BZ2File
是从现有的类似文件的对象构造的,则关闭 BZ2File
不会关闭基础流(这就是您在这里想要的)。
我没有测量多少字节最适合分块,但我猜每 1-20 兆字节 - 它肯定需要大于 bzip2 块大小 (900k)。
另请注意,如果记录每个块的压缩和未压缩偏移量,则可以进行相当高效的随机访问。这就是 dictzip
程序的工作方式,尽管它基于 gzip
.
如果你绝对必须在解压时使用pbzip2
这对你没有帮助,但替代lbzip2
可以执行"normal" .bz2
文件的多核解压,例如与 Python 的 BZ2File
或传统的 bzip2
命令生成的一样。这避免了您描述的 pbzip2
的限制,如果文件也使用 pbzip2
压缩,它只能实现并行解压缩。参见 https://lbzip2.org/。
作为奖励,基准测试表明 lbzip2
在解压缩(30%)和压缩(40%)方面比 pbzip2
快得多,同时实现了略微优越的压缩率。此外,它的 RAM 使用峰值不到 pbzip2
使用的 RAM 的 50%。参见 https://vbtechsupport.com/1614/。