自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

提升您的 Go 應用性能的六種方法

開發(fā) 后端
由于我們的應用程序在 Kubernetes 環(huán)境中的節(jié)點上運行,當我們的 Go 應用程序開始運行時,它可以擁有與節(jié)點中的核心數(shù)量一樣多的線程。

優(yōu)化您的 Go 應用程序

1. 如果您的應用程序在 Kubernetes 中運行,請自動設置 GOMAXPROCS 以匹配 Linux 容器的 CPU 配額

Go 調度器 可以具有與運行設備的核心數(shù)量一樣多的線程。由于我們的應用程序在 Kubernetes 環(huán)境中的節(jié)點上運行,當我們的 Go 應用程序開始運行時,它可以擁有與節(jié)點中的核心數(shù)量一樣多的線程。由于許多不同的應用程序在這些節(jié)點上運行,因此這些節(jié)點可能包含相當多的核心。

通過使用 https://github.com/uber-go/automaxprocs,Go 調度器使用的線程數(shù)量將與您在 k8s yaml 中定義的 CPU 限制一樣多。

示例:

應用程序 CPU 限制(在 k8s.yaml 中定義):1 核心 節(jié)點核心數(shù)量:64

通常情況下,Go 調度器會嘗試使用 64 個線程,但如果我們使用 automaxprocs,它將僅使用一個線程。

我觀察到在我實施這個方法的應用程序中有相當大的性能提升。約 60% 的 CPU 使用率,約 30% 的內存使用率和約 30% 的響應時間。

2. 對結構體字段進行排序

結構體中字段的順序直接影響您的內存使用情況。

例如:

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

您可能會認為這個結構體將占用 18 字節(jié),但實際上不會。

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

這是因為在 64 位架構中內部內存對齊的工作方式。

many boxes showing 8 bytes of testbool1, testFIoat1, testbool2, testFIoat2

我們如何降低內存使用?我們可以根據(jù)內存填充來對字段進行排序。

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
}

我們并不總是需要手動排序這些字段。您可以使用諸如 fieldalignment 等工具來自動對結構體進行排序。

fieldalignment -fix ./... 

3. 垃圾回收調優(yōu)

在 Go 1.19 之前,我們只能使用 GOGC(runtime/debug.SetGCPercent) 來配置垃圾回收周期;然而,在某些情況下,我們可能會超出內存限制。隨著 Go 1.19 的到來,我們現(xiàn)在擁有了 GOMEMLIMIT。GOMEMLIMIT 是一個新的環(huán)境變量,允許用戶限制 Go 進程可以使用的內存量。這個功能提供了更好的控制 Go 應用程序內存使用的方式,防止它們使用過多的內存導致性能問題或崩潰。通過設置 GOMEMLIMIT 變量,用戶可以確保其 Go 程序在系統(tǒng)上平穩(wěn)高效地運行,而不會對系統(tǒng)造成不必要的壓力。

它并不替代 GOGC,而是與之配合使用。您還可以禁用 GOGC 百分比配置,只使用 GOMEMLIMIT 來觸發(fā)垃圾回收。

GOGC 設為 100 和內存限制為 100MB

GOGC 設為關閉(off)并且內存限制為 100

在減少垃圾回收的運行量方面有明顯的效果,但在應用此設置時需要小心。如果您不了解應用程序的極限,請不要將 GOGC=off。

4. 使用 unsafe 包進行字符串 <-> 字節(jié)轉換而不進行復制

在字符串與字節(jié)之間進行轉換時,我們通常會進行變量的復制。但在 Go 內部,這兩種類型通常使用 StringHeader 和 SliceHeader 值。我們可以在這兩種類型之間進行轉換,而不進行額外的分配。

// 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 等庫也在其內部使用這種結構。

注意: 如果您的字節(jié)或字符串值可能會在后續(xù)發(fā)生更改,請不要使用此特性。

5. 使用 jsoniter 替代 encoding/json

我們通常在代碼中使用 Marshal 和 Unmarshal 方法來進行序列化或反序列化。

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 來減少堆分配

對象池背后的主要概念是避免重復創(chuàng)建和銷毀對象的開銷,這可能會對性能產生負面影響。

緩存先前分配但未使用的項目有助于減輕垃圾回收器的負擔,并允許稍后重新使用它們。

以下是一個示例:

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 中的內存泄漏問題。以前,它為每個請求創(chuàng)建一個新的 gzip writer。我創(chuàng)建了一個池,以便代理程序可以使用該池中的 writer,而不是為每個請求創(chuàng)建新的 gzip writer 實例,從而大大減少了堆使用,并因此減少了系統(tǒng)的垃圾回收次數(shù)。這個改進大約將我們應用程序的 CPU 使用率降低了約 40%,內存使用率降低了約 22%。

責任編輯:趙寧寧 來源: 技術的游戲
相關推薦

2016-10-25 10:12:13

2011-02-24 10:56:34

人才

2010-10-08 11:13:22

MySQL修改密碼

2016-07-08 15:02:47

云計算

2023-09-06 08:00:00

ChatGPT數(shù)據(jù)分析

2025-01-02 08:21:32

2022-07-11 10:07:45

云計算網(wǎng)絡云網(wǎng)絡

2021-12-06 06:58:50

List重復數(shù)據(jù)

2022-06-09 08:46:58

ITCIO職業(yè)

2025-01-03 08:48:20

列表推導式Python編程

2022-06-10 10:25:07

CIOIT領導者職業(yè)生涯

2023-04-26 08:41:16

Git撤消更改

2023-04-03 20:29:00

Linux環(huán)境變量

2023-05-15 18:32:20

2023-11-06 08:01:09

Go同步異步

2022-02-21 22:47:36

首席信息官IT技術

2022-05-30 16:42:20

數(shù)據(jù)中心

2024-11-05 08:28:50

2023-12-08 08:53:37

數(shù)據(jù)中心人工智能自動化

2015-07-09 10:13:05

IT基礎設施支出數(shù)據(jù)中心
點贊
收藏

51CTO技術棧公眾號