这几个常用的 Go 官方库,性能居然还不如三方开源库

本文介绍了几个Go语言的高性能库,如fasthttp替换net/http以提高HTTP性能,jsoniter优化json解析速度,以及gogo/protobuf和valyala/quicktemplate在各自领域的高效表现。学习这些库可解决官方库性能瓶颈,但需注意兼容性和版本管理问题。

Go 语言官方库给我们一贯的印象是:强大、好用。但是,金无足赤,人无完人,在一些性能要求苛刻的场景例如 json 解析,某些官方库的表现不尽如人意。

本文介绍几个对标官方库的开源库,它们的性能远超前者。当读者在使用这些官方库遇到性能问题时,可以尝试替换优化。

net/http -> fasthttp

地址:https://github.com/valyala/fasthttp

fasthttp号称比net/http快十倍,其优化的核心思路很简单:资源复用。

  • 复用 goroutine,减轻 runtime 调度压力;

  • 对象复用,大量使用 sync.Pool 减轻 GC 压力。

除了复用,还有其他的一些优化手段,例如尽量避免 string 与 []byte 的转换开销等。

这些优化技巧和最佳实践,在其 Github 主页上已经贴心给出:https://github.com/valyala/fasthttp#fasthttp-best-practices,建议阅读学习。

因为fasthttp的实现与标准库差距较大,所以它与net/http的 API 接口是不同的,这导致从net/http重构为fasthttp需要一些学习成本。

使用fasthttp的知名项目:Fiber、Gearbox、atreugo 等。

encoding/json -> jsoniter

地址:https://github.com/json-iterator/go

jsoniter(json-iterator)是一款快且灵活的 JSON 解析器,同时提供 Java 和 Go 两个版本。官方称 Golang 版本可以比标准库(encoding/json)快 6 倍之多。

65e76b8b1665318d0c060c537d838222.png

最重要的是,它与标准库encoding/json完全兼容。

  • Marshal()

# encoding/json 
import "encoding/json"
json.Marshal(&data)

# jsoniter
import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)
  • Unmarshal()

# encoding/json
import "encoding/json"
json.Unmarshal(input, &data)

# jsoniter
import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal(input, &data)

对其优化原理感兴趣的读者可以看这里:http://jsoniter.com/benchmark.html#optimization-used

golang/protobuf -> gogo/protobuf

地址:https://github.com/gogo/protobuf

ProtoBuf 的全称是 Protocol Buffers,它是由 Google 开发和定义的与 XML、JSON 类似的一种协议格式,用于高效存储与读取结构化数据。它基于二进制,因此使用 ProtoBuf 能将数据压缩得更小。

gogo/protobuf是基于官方库golang/protobuf的增强版实现:

  • golang/protobuf更快地序列化与反序列化;

  • 更规范的 Go 结构;

  • 兼容golang/protobuf

  • 可选地生成额外的帮助代码,减少代码输入;

  • 可以生成测试代码和 benchmark 代码;

  • 其他序列化格式;

有很多知名项目都在使用该库,例如 etcd、k8s、docker swarmkit、tidb、nakama 等。

html/template -> valyala/quicktemplate

地址:https://github.com/valyala/quicktemplate

quicktemplate启发自 Python 的 Mako 项目,是一个快速、强大且易于使用的 Go 模板渲染引擎,它的主要特性如下:

  • quicktemplate会先将编写的模板代码转换为 Go 语言代码,再进行编译渲染。因此,它比标准库html/template快 20 倍以上。

  • quicktemplate的语法与 Go 语法非常类似,几乎没有学习成本。

  • 几乎所有的 bug 都能在模板编译时被捕获,因此在实际项目中,很少会有受模板相关的bug影响。

  • 模板中可以嵌入任意 Go 代码。

虽然quicktemplate的主要目的是生成 HTML,但它也可用于生成其他数据。

例如,使用quicktemplate可以轻松实现 JSON 和 XML 序列化,并且通过quicktemplate的序列化通常也会比通过标准库encoding/jsonencoding/xml更快。

总结

本文列出这几个库并不是让你去立刻替换官方库。例如net/http包,实际上它已经可以满足大多数使用场景。

在使用官方库时遇到了问题,我们很容易通过搜索引擎找到解决方案,或者直接向 Go 官方提 issue 。当切换为开源库时,如果遇到了问题,并不一定能及时得到处理。

官方库的 API 几乎可以保证能与 Go 版本的迭代一直兼容,而三方库可能存在潜在的版本兼容问题,这也是切换时需要考虑的问题。

本文列出来的几个开源库,它们的重点都是优化对应官方库的性能问题。我们可以从这些开源库中,学到很多实用的 Go 代码优化技巧。

当然,如果你的项目中因为这些官方库而导致了性能问题,不妨一试。

感谢你的点赞在看哦~

a87cfe6d39f54dfe167ab7d55bcfc269.gif

三方开源库是指由第三方组织或个人开发并开源的软件库,通常用于提供特定功能或解决特定问题。这些库可以被开发者自由地使用、修改和分发,通常遵循某种开源许可证(如MIT、Apache、GPL等)。三方开源库在软件开发中扮演着重要角色,能够显著提高开发效率,减少重复劳动,促进技术共享和协作。 ### 三方开源库的特点 1. **开源性**:三方开源库的源代码是公开的,任何人都可以查看、修改和贡献代码。这种透明性有助于提高代码质量,并促进社区的发展。 2. **可重用性**:这些库通常封装了某些通用功能,开发者可以直接引入项目中,而无需从头开始编写代码。例如,网络请求库、图像处理库等功能模块可以被多个项目复用。 3. **社区支持**:大多数三方开源库都有活跃的社区,开发者可以在社区中获取帮助、报告问题或提交贡献。社区的支持使得这些库能够持续更新和改进。 4. **许可证约束**:虽然三方开源库是免费使用的,但它们通常遵循特定的开源许可证。开发者在使用时需要遵守相应的许可条款,例如在分发项目时可能需要保留原始版权声明或提供许可证文件。 5. **版本管理**:三方开源库通常会通过版本控制系统进行管理,开发者可以根据需求选择使用特定版本的库,确保项目的稳定性和兼容性。 ### 三方开源库的应用场景 1. **功能扩展**:三方开源库可以帮助开发者快速实现某些复杂的功能,例如网络通信、数据库操作、图像处理等。通过引入这些库,开发者可以专注于业务逻辑的实现,而不是底层技术细节。 2. **跨平台开发**:某些三方开源库支持跨平台开发,例如React Native、Flutter等框架,允许开发者使用一套代码同时构建iOS和Android应用。 3. **快速原型开发**:在项目初期,开发者可以借助三方开源库快速搭建原型,验证产品概念。这有助于缩短开发周期,降低开发成本。 4. **优化性能**:一些三方开源库专注于性能优化,例如内存管理、缓存机制等。开发者可以通过引入这些库来提升应用的性能和用户体验。 5. **集成第三方服务**:许多三方开源库用于集成第三方服务,例如社交分享、消息推送、云存储等。这些库通常提供了简洁的API接口,简化了与外部服务的交互过程。 ### 三方开源库的优势与挑战 1. **优势**: - **提高开发效率**:通过复用已有的开源库,开发者可以节省大量时间,专注于核心功能的实现。 - **降低开发成本**:使用开源库可以减少重复开发的工作量,从而降低开发成本。 - **促进技术共享**:开源库的开放特性促进了技术的共享和传播,推动了技术的进步。 - **社区支持**:活跃的社区可以为开发者提供及时的帮助和技术支持。 2. **挑战**: - **安全性问题**:由于开源库的源代码是公开的,可能存在安全漏洞。开发者需要定期检查库的安全性,并及时更新到最新版本。 - **兼容性问题**:不同版本的开源库可能存在兼容性问题,开发者需要仔细测试库与项目的兼容性。 - **依赖管理**:引入多个开源库可能会导致依赖冲突,增加项目的复杂性。开发者需要合理管理库之间的依赖关系。 - **许可证合规**:开发者在使用开源库时需要遵守相应的许可证条款,否则可能会面临法律风险。 ### 示例:iOS 中常用三方开源库 - **网络通信**:`AFNetworking` 和 `Alamofire` 是 iOS 开发中常用的网络请求库,简化了 HTTP 请求的处理。 - **图像处理**:`SDWebImage` 提供了高效的图片加载和缓存机制,广泛应用于图片展示场景。 - **社交分享**:`ShareSDK` 和 `UMSocial` 是常见的社交分享库,支持多种社交平台的集成。 - **数据库操作**:`FMDB` 是一个轻量级的 SQLite 数据库封装库,适用于 iOS 项目中的本地数据存储。 - **音视频处理**:`GPUImage` 是一个强大的图像和视频处理库,支持实时滤镜效果的实现。 ### 代码示例:使用 `AFNetworking` 进行网络请求 ```objective-c #import "AFNetworking.h" - (void)fetchData { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; [manager GET:@"https://api.example.com/data" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"Response: %@", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"Error: %@", error); }]; } ``` ### 示例:使用 `SDWebImage` 加载网络图片 ```objective-c #import <SDWebImage/UIImageView+WebCache.h> - (void)loadImageWithURL:(NSString *)urlString { NSURL *url = [NSURL URLWithString:urlString]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; [imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeholder"]]; [self.view addSubview:imageView]; } ``` ### 示例:使用 `FMDB` 进行数据库操作 ```objective-c #import "FMDB.h" - (void)createDatabase { NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"test.db"]; FMDatabase *db = [FMDatabase databaseWithPath:path]; if ([db open]) { [db executeUpdate:@"CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)"]; [db executeUpdate:@"INSERT INTO items (name) VALUES (?)", @"Item 1"]; FMResultSet *results = [db executeQuery:@"SELECT * FROM items"]; while ([results next]) { NSLog(@"Item: %@", [results stringForColumn:@"name"]); } [db close]; } } ``` ### 示例:使用 `GPUImage` 实现滤镜效果 ```objective-c #import "GPUImage.h" - (void)applyFilterToImage:(UIImage *)inputImage { GPUImagePicture *picture = [[GPUImagePicture alloc] initWithImage:inputImage]; GPUImageSepiaFilter *filter = [[GPUImageSepiaFilter alloc] init]; [picture addTarget:filter]; [filter useNextFrameForImageCapture]; [picture processImage]; UIImage *filteredImage = [filter imageFromCurrentFramebuffer]; UIImageView *imageView = [[UIImageView alloc] initWithImage:filteredImage]; [self.view addSubview:imageView]; } ``` ### 总结 三方开源库在现代软件开发中具有重要意义,它们不仅提高了开发效率,还促进了技术的共享和创新。然而,开发者在使用三方开源库时也需要注意安全性、兼容性和许可证合规等问题。合理选择和管理开源库,能够为项目带来显著的优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值