当前位置: 首页 > news >正文

Golang高效合并(拼接)多个gzip压缩文件

有时我们可能会遇到需要把多个 gzip 文件合并成单个 gzip 文件的场景,最简单最容易的方式是把每个gzip文件都先解压,然后合并成一个文件后再次进行压缩,最终得到我们想要的结果,但这种先解压后压缩的方式显然效率不高,有没有更好的实现方式呢,答案是肯定的,Linux下常用的压缩库 Zlib 的两位主要作者之一 Mark Adler 就给我们提供了一个这样的示例程序:

https://github.com/madler/zlib/blob/develop/examples/gzjoin.c

在这里插入图片描述
从说明中我们可以看出,这种方式只需要解压一遍所有文件(用于找到特定的比特位并修改它),但不需要做任何额外的压缩操作,而且合并后的 gzip 文件末尾的 crc32 校验和也不需要从头计算(根据源 gzip 文件的校验和用函数 crc32_combine 便可计算出),一般来说,deflate 解压操作要比压缩操作速度快很多,所以这种合并 gzip 文件的方式在性能上是相当高效的,如果是在 C 语言中实现,我们就可以直接“借鉴” Mark Adler 大佬的代码。

针对同一个数据源,用 Go 内置 compress/gzip 包,压缩和解压缩简单的性能对比:

goos: darwin
goarch: arm64
pkg: go-redis-demo
BenchmarkGzipgoredis_test.go:60: test input data length: 778785
BenchmarkGzip/compress
BenchmarkGzip/compress-8         	     115	   9727792 ns/op
BenchmarkGzip/decompress
BenchmarkGzip/decompress-8       	     609	   1957044 ns/op

使用默认压缩级别,解压速度是压缩速度的5倍,使用 Linux 下的命令行压缩工具 gzip 对比结果也差不多:

命令行工具 gzip 压缩速度:

$ ll test.html 
-rw-r--r--  1 zy  staff  778785 Jul 30 14:28 test.html
$ 
$ time gzip -kf test.htmlreal    0m0.034s
user    0m0.024s
sys     0m0.007s
$ time gzip -kf test.htmlreal    0m0.032s
user    0m0.025s
sys     0m0.004s
$ time gzip -kf test.htmlreal    0m0.030s
user    0m0.025s
sys     0m0.004s

命令行工具 gzip 解压缩速度:

$ ll
total 1808
-rw-r--r--  1 zy  staff  778785 Jul 30 14:28 test.html
-rw-r--r--  1 zy  staff  142127 Jul 30 14:28 test.html.gz
$ 
$ time gzip -dkf test.html.gzreal    0m0.013s
user    0m0.003s
sys     0m0.005s
$ time gzip -dkf test.html.gzreal    0m0.008s
user    0m0.003s
sys     0m0.004s
$ time gzip -dkf test.html.gzreal    0m0.010s
user    0m0.003s
sys     0m0.004s

解压也是比压缩快 3-4 倍左右,这就意味着在合并 gzip 文件时省去压缩操作会对性能产生极大提升。

Go 语言实现

用 Go 内置的 compress/gzip 或者 compress/flate 包无法实现与 gzjoin.c 相同的功能,因为 gzjoin.c 的实现依赖解压时的 Z_BLOCK 刷写模式,而 compress/flate 解压缩时并不支持指定 Flush 模式,所以我们只能换一种思路,利用 cgo 来直接调用 Zlib C 库,具体实现可以参考我这里的代码 https://github.com/zhyee/deflatejoin,如果对实现细节不感兴趣,也可以在你的Go项目中直接调用该module, 与用 解压 --> 合并文件 --> 再压缩 的方式性能对比差不多提升了10倍以上:

goos: darwin
goarch: arm64
pkg: github.com/zhyee/deflatejoin
BenchmarkConcatGzip/concat-standard-go-8                       9         123559972 ns/op         1257826 B/op       1261 allocs/op
BenchmarkConcatGzip/concat-deflatejoin-8                     100          10784015 ns/op           30289 B/op         41 allocs/op

相关文章:

Golang高效合并(拼接)多个gzip压缩文件

有时我们可能会遇到需要把多个 gzip 文件合并成单个 gzip 文件的场景,最简单最容易的方式是把每个gzip文件都先解压,然后合并成一个文件后再次进行压缩,最终得到我们想要的结果,但这种先解压后压缩的方式显然效率不高,…...

MySQL数据库-基本概念

数据 描述事物的符号记录包括属组、文字、图形、图像、声音、档案记录等以“记录”形式按统一的格式进行存储 表 将不同的记录组织在一起用来存储具体数据 数据库 表的集合,是以一定的组织方式存储的相互有关的数据集合 数据库管理系统(DBMS&#…...

【无标题】web+http协议+nginx搭建+nginx反向代理(环境准备)

一.Web 为用户提供互联网上浏览信息的服务,web服务是动态的,可交互的。 1.安装httpd yum -y install httpd 2.启动 systemctl start httpd 3.关闭防火墙 systemctl stop firewalld [rootrs html]# echo "我手机号是" > …...

c-periphery RS485串口库文档serial.md(serial.h)(非阻塞读)(VMIN、VTIME)

c-peripheryhttps://github.com/vsergeev/c-periphery 文章目录 NAMESYNOPSISENUMERATIONS关于奇偶校验枚举类型 DESCRIPTIONserial_new()serial_open()关于流控制软件流控制(XON/XOFF)硬件流控制(RTS/CTS)选择流控制方法 serial_…...

Matlab arrayfun 与 bsxfun——提高编程效率的利器!

许多人知道 MATLAB 向量化编程,少用 for 循环 可以提高代码运行效率,但关于代码紧凑化编程, arrayfun 与 bsxfun 两个重要函数却鲜有人能够用好,今天针对这两个函数举例说明其威力。 Matlab arrayfun 概述 arrayfun 是 Matlab …...

【Unity编辑器拓展】GraphView自定义可视化节点

1、创建节点区域脚本 其中的new class UxmlFactory,可以让该元素显示在UI Builder中,我们就可以在Library-Project中看到我们新建的这两个UI元素,就可以拖入我们的UI窗口编辑了 public class NodeTreeViewer : GraphView {public new class…...

教程系列4 | 趋动云『社区项目』极速体验 LivePortrait 人脸表情“移花接木”大法

LivePortrait LivePortrait 由快手可灵大模型团队开源,只需 1 张原图就能生成动态视频。 LivePortrait 的核心优势在于其卓越的表情"迁移"技术,能够令静态图像中的人物瞬间焕发活力,无论是眨眼、微笑还是转头,皆栩栩如…...

WGS84、GCJ-02、BD09三大坐标系详解

文章目录 前言WGS84坐标系定义应用WGS84 Web 墨卡托投影 GCJ-02坐标系(火星坐标系)定义应用GCJ-02经纬度投影与Web墨卡托投影 BD09坐标系(百度坐标系)定义应用BD09经纬度投影与Web墨卡托投影 坐标系之间的区别与注意事项总结 前言…...

css上下动画 和淡化

.popup_hidden_bg { transition: opacity .5s ease-out; opacity: 0; pointer-events: none; /* 防止在隐藏时仍然能点击 */ } keyframes popupShop { from { transform: translateY(100%); opacity: 0; } to {transform: translateY(0);opacity: 1; }} keyframes popupHidd…...

深入解析C#中的URI和URL编码:理解EscapeDataString、EscapeUriString和UrlEncode的区别及字符编码错误处理

在C#中,处理URI(统一资源标识符)和URL(统一资源定位符)时,可以使用Uri.EscapeDataString、Uri.EscapeUriString和HttpUtility.UrlEncode(或WebUtility.UrlEncode)方法来编码字符串。…...

【CSS】给图片设置 max-width

.logo img{width:100%; /* 缩成父盒子的100% */max-width:100%; /* (谁小用谁的百分之百) *//* max-width:100%;【1】图片比盒子大,缩成父盒子的100%【2】图片比盒子小,图片自身的100%*/ }示例 设置样式 .el-image {width: 100%;max-width: 100%;max-…...

区块链——代码格式检查(prettier、solhint)

一、引入依赖 // 导入prettier prettier-plugin-solidity yarn add --dev prettier prettier-plugin-solidity yarn add --dev solhint二、创建.prettierrc文件 {"tabWidth": 2,"semi": false,"useTabs": false,"singleQuote": fals…...

搭建自动化 Web 页面性能检测系统 —— 部署篇

作为一个前端想去做全栈的项目时,可能第一个思路是 node vue/react。一开始可能会新建多个工程目录去实现,假设分别为 web 和 server,也许还有管理后台的代码 admin,那么就有了三个工程的代码。此时为了方便管理就需要在远程仓库…...

知识图谱增强的RAG(KG-RAG)详细解析

转自:知识图谱科技 这是一个与任务无关的框架,它将知识图谱(KG)的显性知识与大型语言模型(LLM)的隐含知识结合起来。这是该工作的arXiv预印本 https://arxiv.org/abs/2311.17330 。 我们在这里利用一个名为…...

python中list的深拷贝和浅拷贝

其实这还是涉及到python中的可变对象和不可变对象的概念。 https://www.cnblogs.com/poloyy/p/15073168.html # -*- coding: utf-8 -*-person [name, [savings, 100.00]] hubby person[:] # slice copy wifey list(person) # fac func copy a [id(x) for x in person] b …...

【LeetCode】字母异位词分组

题目描述: 给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] 输出: [[“bat”…...

Golang | Leetcode Golang题解之第295题数据流的中位数

题目: 题解: type MedianFinder struct {nums *redblacktree.Treetotal intleft, right iterator }func Constructor() MedianFinder {return MedianFinder{nums: redblacktree.NewWithIntComparator()} }func (mf *MedianFinder) AddNum(…...

【C语言】C语言期末突击/考研--数据的输入输出

目录 一、printf()输出函数介绍 二、scanf读取标准输入 (一)scanf函数的原理 (二)多种数据类型混合输入 三、练习题 今天我们学习printf和scanf读取标准输入。下面我们开始正式的学习吧。 C语言中有很多内置函数,今…...

How can I fix my Flask server‘s 405 error that includes OpenAi api?

题意:解决包含OpenAI API的Flask服务器中出现的405错误(Method Not Allowed,即方法不允许) 问题背景: Im trying to add an API to my webpage and have never used any Flask server before, I have never used Java…...

LeetCode Hot100 将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 平衡 二叉搜索树。 示例 1: 输入:nums [-10,-3,0,5,9] 输出:[0,-3,9,-10,null,5] 解释:[0,-10,5,null,-3,null,9] 也将被视为正确…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

【Oracle APEX开发小技巧12】

有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

Unity中的transform.up

2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await&#xf…...

Windows 下端口占用排查与释放全攻略

Windows 下端口占用排查与释放全攻略​ 在开发和运维过程中,经常会遇到端口被占用的问题(如 8080、3306 等常用端口)。本文将详细介绍如何通过命令行和图形化界面快速定位并释放被占用的端口,帮助你高效解决此类问题。​ 一、准…...

Qt Quick Controls模块功能及架构

Qt Quick Controls是Qt Quick的一个附加模块,提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中,这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构,与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...