通过多线程压缩提高生成 Zip 文件的效率

本文探讨了在处理大型数据文档时,如何通过使用多线程和miniz库实现快速压缩Zip文件的方法。通过将单个文件压缩任务并行化,有效减少了压缩时间,即使内存操作增加,整体效率仍显著提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在很多情况下,需要用 Zip 格式保存数据文档。当数据量较大时(超过100M),就会明显感觉到保存文件耗时很长(超过10秒),这样的用户体验难以接受,想要优化。

现有开源方案

zlib-ng/zlib-ng支持特殊指令提升效率下一代 zlib,需要集成到 gzip 中
pigz - Parallel gzip多线程并行提高效率只支持命令行模式允许,没有 API
miniZ支持 GPU商用,需要收费

 综上,没有特别满足需求的开源方案,所以下面介绍一个简单的多线程压缩方案。

多线程多文件方案

我们的多线程压缩方案一个重要前提是:需要压缩多个文件,保存到一个 zip 中。

该方案不是特别依赖某一个 gzip 开发库,我们用的是 minz,只是作为一个例子,如果使用其他  gzip 开发库,也应该很容易基于它实现该方案。

该方案的核心思想,是将每个文件的压缩作为一个任务,每个任务生成一个包含单文件的 zip 包(在内存中生成,不一定要写文件),然后合并到主 zip 包中。任务可以在线程池中并行执行,只是合并时,需要串行执行。

即使多了一些内存拷贝操作,最后的步骤也必须串行执行,但是因为大部分消耗是在压缩算法上,最终的效果还是很不错的,我的 6核(12逻辑核心)的 CPU,也能够将时间减少到原来的 1/10。

方案实现

并行执行

使用 Threading Building Blocks (TBB),可以极大简化并行任务调度

std::vector<std::string> files;
boost::mutex mutex;
tbb::parallel_for(tbb::blocked_range<size_t>(0, files.size(), 1), 
        [&files, &root_zip, &mutex](const tbb::blocked_range<size_t>& range) {
    for (int i = range.begin(); i < range.end(); ++i) {
        auto file = files[i];
        // 压缩 file 到 zip
        {
            boost::unique_lock l(mutex);
            // 合并 zip 到 root_zip
        }
    }
});

这只是 tbb 的小试牛刀。

压缩 zip

// 压缩到内存
mz_zip_archive archive;
mz_zip_writer_staged_context context;
mz_zip_zero_struct(&archive);
mz_zip_writer_init_heap(&archive, 0, 1024 * 1024);
mz_zip_writer_add_file(&archive, file.c_str(), file.c_str());
// 取出内存指针
void *ppBuf; size_t pSize;
mz_zip_writer_finalize_heap_archive(&archive, &ppBuf, &pSize);
mz_zip_writer_end(&archive);
// 用读模式重新打开
mz_zip_zero_struct(&archive);
mz_zip_reader_init_mem(&archive, ppBuf, pSize, 0);

合并 zip

{
    boost::unique_lock l(mutex);
    mz_zip_writer_add_from_zip_reader(&root_archive, &archive, 0);
}
mz_zip_reader_end(&archive);

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值