当前位置:首页 > 科技  > 软件

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

来源: 责编: 时间:2023-11-07 17:16:57 396观看
导读优化您的 Go 应用程序1. 如果您的应用程序在 Kubernetes 中运行,请自动设置 GOMAXPROCS 以匹配 Linux 容器的 CPU 配额Go 调度器 可以具有与运行设备的核心数量一样多的线程。由于我们的应用程序在 Kubernetes 环境中

优化您的 Go 应用程序

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

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

通过使用 https://github.com/uber-go/automaxprocs,Go 调度器使用的线程数量将与您在 k8s yaml 中定义的 CPU 限制一样多。UT728资讯网——每日最新资讯28at.com

示例:UT728资讯网——每日最新资讯28at.com

应用程序 CPU 限制(在 k8s.yaml 中定义):1 核心 节点核心数量:64UT728资讯网——每日最新资讯28at.com

通常情况下,Go 调度器会尝试使用 64 个线程,但如果我们使用 automaxprocs,它将仅使用一个线程。UT728资讯网——每日最新资讯28at.com

我观察到在我实施这个方法的应用程序中有相当大的性能提升。约 60% 的 CPU 使用率,约 30% 的内存使用率和约 30% 的响应时间。UT728资讯网——每日最新资讯28at.com

UT728资讯网——每日最新资讯28at.com

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

结构体中字段的顺序直接影响您的内存使用情况。UT728资讯网——每日最新资讯28at.com

例如:UT728资讯网——每日最新资讯28at.com

type testStruct struct { testBool1  bool    // 1 byte testFloat1 float64 // 8 bytes testBool2  bool    // 1 byte testFloat2 float64 // 8 bytes}

您可能会认为这个结构体将占用 18 字节,但实际上不会。UT728资讯网——每日最新资讯28at.com

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

这是因为在 64 位架构中内部内存对齐的工作方式。UT728资讯网——每日最新资讯28at.com

UT728资讯网——每日最新资讯28at.com

many boxes showing 8 bytes of testbool1, testFIoat1, testbool2, testFIoat2UT728资讯网——每日最新资讯28at.com

我们如何降低内存使用?我们可以根据内存填充来对字段进行排序。UT728资讯网——每日最新资讯28at.com

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

UT728资讯网——每日最新资讯28at.com

我们并不总是需要手动排序这些字段。您可以使用诸如 fieldalignment 等工具来自动对结构体进行排序。UT728资讯网——每日最新资讯28at.com

fieldalignment -fix ./... 

3. 垃圾回收调优

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

它并不替代 GOGC,而是与之配合使用。您还可以禁用 GOGC 百分比配置,只使用 GOMEMLIMIT 来触发垃圾回收。UT728资讯网——每日最新资讯28at.com

UT728资讯网——每日最新资讯28at.com

GOGC 设为 100 和内存限制为 100MBUT728资讯网——每日最新资讯28at.com

UT728资讯网——每日最新资讯28at.com

GOGC 设为关闭(off)并且内存限制为 100UT728资讯网——每日最新资讯28at.com

在减少垃圾回收的运行量方面有明显的效果,但在应用此设置时需要小心。如果您不了解应用程序的极限,请不要将 GOGC=off。UT728资讯网——每日最新资讯28at.com

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

在字符串与字节之间进行转换时,我们通常会进行变量的复制。但在 Go 内部,这两种类型通常使用 StringHeader 和 SliceHeader 值。我们可以在这两种类型之间进行转换,而不进行额外的分配。UT728资讯网——每日最新资讯28at.com

// For Go 1.20 and higherfunc 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 等库也在其内部使用这种结构。UT728资讯网——每日最新资讯28at.com

注意: 如果您的字节或字符串值可能会在后续发生更改,请不要使用此特性。UT728资讯网——每日最新资讯28at.com

5. 使用 jsoniter 替代 encoding/json

我们通常在代码中使用 Marshal 和 Unmarshal 方法来进行序列化或反序列化。UT728资讯网——每日最新资讯28at.com

Jsoniter 是 encoding/json 的 100% 兼容的替代品。UT728资讯网——每日最新资讯28at.com

以下是一些性能基准:UT728资讯网——每日最新资讯28at.com

UT728资讯网——每日最新资讯28at.com

将其替换为 encoding/json 非常简单:UT728资讯网——每日最新资讯28at.com

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

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

对象池背后的主要概念是避免重复创建和销毁对象的开销,这可能会对性能产生负面影响。UT728资讯网——每日最新资讯28at.com

缓存先前分配但未使用的项目有助于减轻垃圾回收器的负担,并允许稍后重新使用它们。UT728资讯网——每日最新资讯28at.com

以下是一个示例:UT728资讯网——每日最新资讯28at.com

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%。UT728资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-17553-0.html提升您的 Go 应用性能的六种方法

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Angular 发布新文档、新 Logo

下一篇: Python:求求按规范写我

标签:
  • 热门焦点
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 一文看懂为苹果Vision Pro开发应用程序

    译者 | 布加迪审校 | 重楼苹果的Vision Pro是一款混合现实(MR)头戴设备。Vision Pro结合了虚拟现实(VR)和增强现实(AR)的沉浸感。其高分辨率显示屏、先进的传感器和强大的处理能力
  • 微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 梁柱接棒两年,腾讯音乐闯出新路子

    文丨田静 出品丨牛刀财经(niudaocaijing)7月5日,企鹅FM发布官方公告称由于业务调整,将于9月6日正式停止运营,这意味着腾讯音乐长音频业务走向消亡。腾讯在长音频领域还在摸索。为
  • iQOO 11S评测:行业唯一的200W标准版旗舰

    【Techweb评测】去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,该机不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞
  • iQOO Neo8 Pro即将开售:到手价3099元起 安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
  • 滴滴违法违规被罚80.26亿 共存在16项违法事实

    滴滴违法违规被罚80.26亿 存在16项违法事实开始于2121年7月,历经一年时间,网络安全审查办公室对“滴滴出行”网络安全审查终于有了一个暂时的结束。据“网信
  • 英特尔Xe HPG游戏显卡:拥有512EU,单风扇版本

    据10 月 30 日外媒 TheVerge 消息报道,英特尔 Xe HPG Arc Alchemist 的正面实被曝光,不仅拥有 512 EU 版显卡,还拥有 128EU 的单风扇版本。另外,这款显卡 PCB
  • “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top