是否可以并行化bz2的解压缩?

时间:2017-09-19 12:47:12

标签: python python-2.7 multiprocessing bzip2 bzip

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

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

当我用pbzip2压缩它时,它可以在解压缩时利用多个核心。有没有办法在pthon中以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()

2 个答案:

答案 0 :(得分:2)

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模式下关闭/重新打开一个流,每个字节都很多,以获得同样的结果。请注意,如果从现有的类文件对象构造BZ2File,则关闭BZ2File将不会关闭基础流(这是您想要的)。

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

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

答案 1 :(得分:0)

如果您绝对必须在解压缩中使用struct ContentView: View { var body: some View { GeometryReader { gr in VStack { HStack { Text("Explore More") .font(.headline) .foregroundColor(.black) .padding(.leading, 20) Spacer() } VStack(spacing: 0) { Grid(leftTitle: "Desert", rightTitle: "Kids") Grid(leftTitle: "Stripes", rightTitle: "Pastels") }.frame(maxWidth: .infinity, maxHeight: gridHeight(gr, count: 2)) .background(Color.red) }.background(Color.orange) } } } // MARK: - Grid struct Grid: View { let leftTitle: String let rightTitle: String @State private var showLeft = false @State private var showRight = false var body: some View { GeometryReader { gr in return HStack(spacing: 12) { Button(action: { self.showLeft = true }) { ZStack { RoundedRectangle(cornerRadius: 20) .frame(maxWidth: width(gr), maxHeight: height(gr)) Text(self.leftTitle) .foregroundColor(.black) .font(.subheadline) } } Button(action: { self.showRight = true }) { ZStack { RoundedRectangle(cornerRadius: 20) .frame(maxWidth: width(gr), maxHeight: height(gr)) Text(self.rightTitle) .foregroundColor(.black) .font(.subheadline) } } }.frame(width: gr.size.width, height: height(gr) + 24, alignment: .center) } } } let horizontalPadding: CGFloat = 20 + 20 + 12 // 20 for each side and 12 in the middle func gridHeight(_ gr: GeometryProxy, count: Int) -> CGFloat { return CGFloat(count) * (height(gr) + 24) } func height(_ gr: GeometryProxy) -> CGFloat { return (gr.size.width - horizontalPadding) / 3 } func width(_ gr: GeometryProxy) -> CGFloat { return (gr.size.width - horizontalPadding) / 2 } ,这将无济于事,但是替代方法pbzip2可以对“正常” lbzip2文件执行多核解压缩,例如由Python的.bz2或传统的BZ2File命令。这避免了您正在描述的bzip2的局限性,即只有在文件也使用pbzip2压缩的情况下,它才能实现并行解压缩。参见https://lbzip2.org/

作为奖励,基准测试表明pbzip2在解压缩(压缩30%)和压缩(压缩40%)方面都比lbzip2快得多,而压缩率却稍高。此外,其峰值RAM使用量少于pbzip2使用的RAM的50%。参见https://vbtechsupport.com/1614/