提升您的 Go 应用性能的 6 种方法

优化您的 Go 应用程序

在这里插入图片描述

1. 如果您的应用程序在 Kubernetes 中运行,请自动设置 GOMAXPROCS 以匹配 Linux 容器的 CPU 配额

Go 调度器 可以具有与运行设备的核心数量一样多的线程。由于我们的应用程序在 Kubernetes 环境中的节点上运行,当我们的 Go 应用程序开始运行时,它可以拥有与节点中的核心数量一样多的线程。由于许多不同的应用程序在这些节点上运行,因此这些节点可能包含相当多的核心。

通过使用 https://github.com/uber-go/automaxprocs,Go 调度器使用的线程数量将与您在 k8s yaml 中定义的 CPU 限制一样多。

示例:

应用程序 CPU 限制(在 k8s.yaml 中定义):1 核心
节点核心数量:64

通常情况下,Go 调度器会尝试使用 64 个线程,但如果我们使用 automaxprocs,它将仅使用一个线程。

我观察到在我实施这个方法的应用程序中有相当大的性能提升。约 60% 的 CPU 使用率,约 30% 的内存使用率和约 30% 的响应时间。

2. 对结构体字段进行排序

结构体中字段的顺序直接影响您的内存使用情况。

例如:

type testStruct struct {testBool1  bool    // 1 bytetestFloat1 float64 // 8 bytestestBool2  bool    // 1 bytetestFloat2 float64 // 8 bytes
}

您可能会认为这个结构体将占用 18 字节,但实际上不会。

func main() {a := testStruct{}fmt.Println(unsafe.Sizeof(a)) // 32 bytes
}

这是因为在 64 位架构中内部内存对齐的工作方式。有关更多信息,您可以阅读这篇文章。

在这里插入图片描述

我们如何降低内存使用?我们可以根据内存填充来对字段进行排序。

type testStruct struct {testFloat1 float64 // 8 bytestestFloat2 float64 // 8 bytestestBool1  bool    // 1 bytetestBool2  bool    // 1 byte
}func main() {a := testStruct{}fmt.Println(unsafe.Sizeof(a)) // 24 bytes
}

img

我们并不总是需要手动排序这些字段。您可以使用诸如 fieldalignment 等工具来自动对结构体进行排序。

fieldalignment -fix ./... 

3. 垃圾回收调优

在 Go 1.19 之前,我们只能使用 GOGC(runtime/debug.SetGCPercent) 来配置垃圾回收周期;然而,在某些情况下,我们可能会超出内存限制。随着 Go 1.19 的到来,我们现在拥有了 GOMEMLIMITGOMEMLIMIT 是一个新的环境变量,允许用户限制 Go 进程可以使用的内存量。这个功能提供了更好的控制 Go 应用程序内存使用的方式,防止它们使用过多的内存导致性能问题或崩溃。通过设置 GOMEMLIMIT 变量,用户可以确保其 Go 程序在系统上平稳高效地运行,而不会对系统造成不必要的压力。

它并不替代 GOGC,而是与之配合使用。您还可以禁用 GOGC 百分比配置,只使用 GOMEMLIMIT 来触发垃圾回收。

在这里插入图片描述

GOGC 设为 100 和内存限制为 100MB

在这里插入图片描述

GOGC 设为关闭(off)并且内存限制为 100。

在减少垃圾回收的运行量方面有明显的效果,但在应用此设置时需要小心。如果您不了解应用程序的极限,请不要将 GOGC=off

4. 使用 unsafe 包进行字符串 <-> 字节转换而不进行复制

在字符串与字节之间进行转换时,我们通常会进行变量的复制。但在 Go 内部,这两种类型通常使用 StringHeaderSliceHeader 值。我们可以在这两种类型之间进行转换,而不进行额外的分配。

// For Go 1.20 and higher
func StringToBytes(s string) []byte {return unsafe.Slice(unsafe.StringData(s), len(s))
}func BytesToString(b []byte) string {return unsafe.String(unsafe.SliceData(b), len(b))
}// For lower versions
// Check the example here
// https://github.com/bcmills/unsafeslice/blob/master/unsafeslice.go#L116

诸如 fasthttp 和 fiber 等库也在其内部使用这种结构。

注意: 如果您的字节或字符串值可能会在后续发生更改,请不要使用此特性。

5. 使用 jsoniter 替代 encoding/json

我们通常在代码中使用 MarshalUnmarshal 方法来进行序列化或反序列化。

Jsoniter 是 encoding/json 的 100% 兼容的替代品。

以下是一些性能基准:

在这里插入图片描述

将其替换为 encoding/json 非常简单:

import "encoding/json"json.Marshal(&data)
json.Unmarshal(input, &data)
import jsoniter "github.com/json-iterator/go"var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)
json.Unmarshal(input, &data)

6. 使用 sync.Pool 来减少堆分配

对象池背后的主要概念是避免重复创建和销毁对象的开销,这可能会对性能产生负面影响。

缓存先前分配但未使用的项目有助于减轻垃圾回收器的负担,并允许稍后重新使用它们。

以下是一个示例:

type Person struct {Name string
}var pool = sync.Pool{New: func() any {fmt.Println("Creating a new instance")return &Person{}},
}func main() {person := pool.Get().(*Person)fmt.Println("Get object from sync.Pool for the first time:", person)person.Name = "Mehmet"fmt.Println("Put the object back in the pool")pool.Put(person)fmt.Println("Get object from pool again:", pool.Get().(*Person))fmt.Println("Get object from pool again (new one will be created):", pool.Get().(*Person))
}//Creating a new instance
//Get object from sync.Pool for the first time: &{}
//Put the object back in the pool
//Get object from pool again: &{Mehmet}
//Creating a new instance
//Get object from pool again (new one will be created): &{}

通过使用 sync.Pool,我解决了 New Relic Go Agent 中的内存泄漏问题。以前,它为每个请求创建一个新的 gzip writer。我创建了一个池,以便代理程序可以使用该池中的 writer,而不是为每个请求创建新的 gzip writer 实例,从而大大减少了堆使用,并因此减少了系统的垃圾回收次数。这个改进大约将我们应用程序的 CPU 使用率降低了约 40%,内存使用率降低了约 22%。

希望对您有所帮助,欢迎提供任何反馈。谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/149381.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全能视频工具 VideoProc Converter 4K for mac中文

VideoProc 4K提供快速完备的4K影片处理方案&#xff0c;您可以透过这款软体调节输出影片格式和大小。能够有效压缩HD/4K影片体积90%以上&#xff0c;以便更好更快地上传到YouTube&#xff0c;或是通过电子邮件附件发送。业界领先的视讯压缩引擎&#xff0c;让你轻松处理大体积视…

计算机网络 快速了解网络层次、常用协议、常见物理设备。 掌握程序员必备网络基础知识!!!

文章目录 0 引言1 基础知识的定义1.1 计算机网络层次1.2 网络供应商 ISP1.3 猫、路由器、交换机1.4 IP协议1.5 TCP、UDP协议1.6 HTTP、HTTPS、FTP协议1.7 Web、Web浏览器、Web服务器1.8 以太网和WLAN1.9 Socket &#xff08;网络套接字&#xff09; 2 总结 0 引言 在学习的过程…

OpenGLES:绘制一个混色旋转的3D球体

效果展示 本博文会实现一个混色旋转的3D球体 一.球体解析 前几篇博文讲解了如何使用OpenGLES实现不同的3D图形 这一篇讲解怎样绘制3D世界的代表图形&#xff1a;一个混色旋转的3D球体 1.1 极限正多面体 如果看过我前几篇3D图形绘制的博文&#xff0c;就知道要绘制一个3D图…

第三课 哈希表、集合、映射

文章目录 第三课 哈希表、集合、映射lc1.两数之和--简单题目描述代码展示 lc30.串联所有单词的子串--困难题目描述代码展示 lc49.字母异位分组--中等题目描述代码展示 lc874.模拟行走机器人--中等题目描述代码展示 lc146.LRU缓存--中等题目描述相关补充思路讲解代码展示图示理解…

正点原子嵌入式linux驱动开发——U-boot启动流程详解

在上一篇笔记中详细分析了uboot的顶层Makefile&#xff0c;理清了uboot的编译流程。本章来详细的分析一下uboot的启动流程&#xff0c;理清uboot是如何启动的。通过对uboot启动流程的梳理&#xff0c;可以掌握一些外设是在哪里被初始化的&#xff0c;这样当需要修改这些外设驱动…

java的内存模型(概念)

在java中&#xff0c;设计之初就有了&#xff1a;主内存、线程工作内存&#xff0c;所以其实每一个线程执行时&#xff0c;都是将主线程copy一份到工作线程&#xff0c;执行修改后&#xff0c;再同步回去。 所以&#xff0c;就有四组内存操作方式&#xff1a; 1、读主内存&…

postgresql-物化视图

postgresql-物化视图 物化视图创建物化视图刷新物化视图修改物化视图删除物化视图 物化视图 创建物化视图 postgresql使用create materialized view 语句创建视图 create materialized view if not exists name as query [with [NO] data];-- 创建一个包含员工统计信息的物化…

自学SLAM(2)---保姆教程教你如何使用自己的视频运行ORB-SLAM2

前言 如果你是新手入门&#xff0c;仅仅只会Linux的基本操作&#xff0c;并看了高翔老师视觉SLAM视屏的第一讲&#xff0c;那么你需要准备一整天的时间&#xff0c;可能还不一定能运行出来&#xff01;运行ORB-SLAM2将会安装很多很多东西。那么&#xff0c;我们准备开始&#x…

CRMEB商城源码开源标准版v5.2.0+后端+前端uni-app开源包安装教程

CRMEB打通版是一款全开源支持商用的PHP多语言商城系统,历经年时间匠心之作&#xff01;系统采用前后端分离技术&#xff0c;基于TP6Uui-app框架开发&#xff1b;客户移动端采用uni-app开发&#xff0c;管理后台前端使用iviewUI开发。系统支持微信公众号端、微信小程序端、H5端、…

C语言之自定义类型_结构体篇(1)

目录 什么是结构&#xff1f; 结构体类型的声明 常规声明 特殊声明-匿名结构体 结构体变量的定义和初始化和访问 定义 初始化 访问 嵌套结构体 结构体的自引用 什么是结构体的自引用 NO1. NO2. 热门考点&#xff1a;结构体内存对齐 产生内存对齐 NO1 NO2 …

二十九、高级IO与多路转接之epollreactor(收官!)

文章目录 一、Poll&#xff08;一&#xff09;定义&#xff08;二&#xff09;实现原理&#xff08;三&#xff09;优点&#xff08;四&#xff09;缺点 二、I/O多路转接之epoll&#xff08;一&#xff09;从网卡接收数据说起&#xff08;二&#xff09;如何知道接收了数据&…

蓝桥杯每日一题2023.9.28

AcWing 4409. 砍竹子 - AcWing 题目描述 题目分析 注&#xff1a;sqrtl的范围为long double&#xff0c;比sqrt更加精确 使用优先队列维护一段区间&#xff0c;如果连续一段相同就合并为一个区间&#xff0c;从大到小去枚举&#xff0c;每次先取出最大的一段&#xff0c;双…

专业综合课程设计 - 优阅书城项目(第一版)

此项目是《专业综合课程设计》带练项目 实现的功能有&#xff1a; 登录、注销、添加图书、删除图书、编辑图书 包含资源&#xff1a; 优阅书城&#xff08;bookstore&#xff09;源码 数据库数据 课程笔记 下载链接&#xff1a;https://wwpv.lanzoue.com/i79nx1av4doj 登录功…

windows系统服务管理命令sc

sc可以用于管理系统服务、计划任务、系统日志等方面&#xff0c;是不可或缺的神器。 基本用法 在命令提示符下输入sc命令&#xff0c;然后按回车键。 上图展示的是sc命令的使用方法&#xff0c;支持哪些参数实现哪些功能 要查看系统所有服务列表&#xff0c;包括它们是否正在…

逻辑回归评分卡

文章目录 一、基础知识点(1)逻辑回归表达式(2)sigmoid函数的导数损失函数(Cross-entropy, 交叉熵损失函数)交叉熵求导准确率计算评估指标 二、导入库和数据集导入库读取数据 三、分析与训练四、模型评价ROC曲线KS值再做特征筛选生成报告 五、行为评分卡模型表现总结 一、基础知…

Go-Python-Java-C-LeetCode高分解法-第八周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接&#xff1a;LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏&#xff0c;每日一题&#xff0c;和博主一起进步 LeetCode专栏 我搜集到了50道精选题&#xff0c;适合速成概览大部分常用算法 突…

2023年-华为机试题库B卷(Python)【满分】

1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ &#x1f51f; 华为机试题库B卷 已于5月10号 更新为2023 B卷 &#xff08;2023-10-04 更新本文&#xff09; 华为机试有三道题目&#xff0c;前两道属于简单或中等题&#xff0c;分值为100分&#xff0c;第三道为中等或…

互动营销类游戏开发小程序游戏开发

互动营销类游戏开发是一种创意和有趣的方式&#xff0c;可以用于推广产品、品牌或服务。这些游戏旨在吸引玩家并与他们互动&#xff0c;以促使他们与您的品牌建立更紧密的联系。 当今数字时代的市场竞争激烈&#xff0c;品牌和企业需要采用创新的方法来吸引并保持用户的兴趣。…

MySQL基础-事务

目录 1.事务简介 2.事务的操作 2.1 实验需要用到的数据 2.2 完成转账操作 修改事务执行方式 手动开启事务的方式 3.事务的四大特性 4.并发事务问题 5.事务隔离级别 5.1 事务隔离级别分类 5.2 查看事务隔离级别 5.3 设置事务隔离级别 1.事务简介 事务是一组操作的集合…

实时人脸五观检测:基于libfacedetection(CNN模型)

一、前言 随着人工智能技术的不断发展,人脸检测已成为计算机视觉领域的重要应用之一。人脸检测是一种将输入图像中的人脸位置和轮廓提取出来的技术,广泛应用于人脸识别、智能监控、人机交互等领域。利用libfacedetection开源的人脸检测库,实现人脸检测。 libfacedetection…