亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Golang應(yīng)用程序性能優(yōu)化技巧分享

 更新時間:2023年04月11日 14:19:42   作者:落風(fēng)雪  
隨著科技的進(jìn)步,人人都想要快速的應(yīng)用,這就需要優(yōu)化您的應(yīng)用程序性能。本文為大家整理了一些Golang應(yīng)用程序性能優(yōu)化的技巧,希望對大家有所幫助

一、概述

隨著科技的進(jìn)步,人人都想要快速的應(yīng)用,用戶想要快速的交付,開發(fā)者想要快速的性能,創(chuàng)業(yè)者想要兩者兼而有之。這就需要優(yōu)化您的應(yīng)用程序性能。您需要提高應(yīng)用程序的速度和性能,使其成為市場上最好的。您想要優(yōu)化 Golang 應(yīng)用程序的主要原因有兩個——資源效率和改善操作延遲。您的應(yīng)用程序的最終目標(biāo)應(yīng)該是它不需要太多資源而繼續(xù)等待操作。盡管您的 Golang 應(yīng)用程序太復(fù)雜以至于無法執(zhí)行其中一項任務(wù),但它必須依賴另一項任務(wù),這樣一來,它就變成了一個死循環(huán)的依賴項。本文將討論一些關(guān)于提高 Golang 應(yīng)用程序性能的最佳實踐。

二、關(guān)于性能優(yōu)化的方向

延遲問題

延遲優(yōu)化需要分析程序的瓶頸。主要目的在于優(yōu)化特定功能的延遲。當(dāng)您提高程序的資源效率時,延遲會自動改善。然而,改善延遲可能需要增加資源消耗。故此,我們需要意識到程序的瓶頸和熱點,并同時處理這些問題。

資源效率

您可以提高應(yīng)用程序性能以優(yōu)化資源使用。程序的某些部分比其他部分需要更多的資源,您應(yīng)該為您的應(yīng)用程序找到這樣的熱點。如 CPU、帶寬或內(nèi)存。

算法效率

通常程序可以采用不同的算法來執(zhí)行相同的操作,但效率往往因為各種因素不一而產(chǎn)生不一樣的效果,所以通過實施算法優(yōu)化,我們可以最大限度地提高應(yīng)用程序的性能。

三、提高 Golang 應(yīng)用程序性能的最佳實踐

1. 并行化 CPU 工作

同步需要花費大量時間,當(dāng)您使用可用內(nèi)核并行工作時,它肯定會優(yōu)化 Golang 應(yīng)用程序性能。這是線性加速應(yīng)用程序執(zhí)行的重要一步。這也屬于Golang相對于其他語言的天然優(yōu)勢(自帶彈藥庫)。另外并行不一定最優(yōu),但能并行的場景,必然對我們有利,因為Golang天生麗質(zhì)。

下面我們以計算也給目錄的文件總大小為例。分別以非并行和并行兩種方式進(jìn)行對比

//非并行版本

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"path/filepath"
	"time"
)

const (
	//目標(biāo)目錄
	TargetPath = "G:\\go"
)

// 遞歸計算目錄下所有文件
func walkDir(path string, fileSize chan<- int64) {
	fmt.Printf("\rwalk ... %s\n", path)
	entries, err := ioutil.ReadDir(path)
	if err != nil {
		log.Fatal(err)
		return
	}
	for _, e := range entries {
		if e.IsDir() {
			walkDir(filepath.Join(path, e.Name()), fileSize)
		} else {
			fileSize <- e.Size()
		}
	}
}

func main() {
	//文件大小chennel
	fileSize := make(chan int64)
	//文件總大小
	var sizeCount int64
	//文件數(shù)目
	var fileCount int

	//計算目錄下所有文件占的大小總和
	go func() {
		walkDir(TargetPath, fileSize)
		defer close(fileSize)
	}()

	t := time.Now()
	for size := range fileSize {
		fileCount++
		sizeCount += size
	}
	fmt.Println("used time: " + time.Since(t).String())
	fmt.Printf("total size: %.1fGB\nfile count: %d\n", float64(sizeCount)/1e9, fileCount)
}

//-------------結(jié)果---------------

used time: 41.6566073s
total size: 8.5GB
file count: 416088

//并行版本

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"path/filepath"
	"sync"
	"time"
)

const (
	//goTest目錄
	TargetPath = "G:\\go"
)

var waitGroup sync.WaitGroup
var ch = make(chan struct{}, 255)

// 遞歸計算目錄下所有文件
func walkDir(path string, fileSize chan<- int64) {
	defer waitGroup.Done()
	fmt.Printf("\rwalk ... %s\n", path)
	ch <- struct{}{} //限制并發(fā)量
	entries, err := ioutil.ReadDir(path)
	<-ch
	if err != nil {
		log.Fatal(err)
		return
	}
	for _, e := range entries {
		if e.IsDir() {
			waitGroup.Add(1)
			go walkDir(filepath.Join(path, e.Name()), fileSize)
		} else {
			fileSize <- e.Size()
		}
	}
}

func main() {
	//文件大小chennel
	fileSize := make(chan int64)
	//文件總大小
	var sizeCount int64
	//文件數(shù)目
	var fileCount int
	//計算目錄下所有文件占的大小總和
	waitGroup.Add(1)
	go walkDir(TargetPath, fileSize)
	go func() {
		defer close(fileSize)
		waitGroup.Wait()
	}()
	t := time.Now()
	for size := range fileSize {
		fileCount++
		sizeCount += size
	}
	fmt.Println("used time: " + time.Since(t).String())
	fmt.Printf("total size: %.1fGB\nfile count: %d\n", float64(sizeCount)/1e9, fileCount)
}
//-------------結(jié)果---------------
used time: 7.3528287s
total size: 8.5GB 
file count: 416088

很明顯,我們采用并行方式后,程序的運行效率提升了接近6倍,所以,我們在適當(dāng)場景下使用合適的方式進(jìn)行并行編程,就能為我們程序帶來意想不到的效果。當(dāng)然上面的代碼有些瑕疵,例如goroutine的創(chuàng)建不應(yīng)該手動,而應(yīng)該使用協(xié)程池等方式。

2.觀察你的超時

通常,輸入輸出操作需要更多時間,從而導(dǎo)致延遲。要克服這個問題,您應(yīng)該避免在不知道其將消耗的時間的情況下執(zhí)行任何 I/O 任務(wù)。在為每個網(wǎng)絡(luò)請求設(shè)置超時之前,您應(yīng)該使用 SetDeadline、SetReadDeadline 和 SetWriteDeadline。

3. 使 I/O 操作異步

最常見的瓶頸是由于網(wǎng)絡(luò)事務(wù)和文件輸入/輸出執(zhí)行造成的。因此,為了優(yōu)化您的 Golang 應(yīng)用程序性能,您可以使獨立的 I/O 異步。以這種方式,此類操作并行運行并改善下游延遲。此外,您可以使用 sync.WaitGroup 來同步多個 I/O 操作。

4.減少Goroutines的使用

使用 Goroutines 非常便宜且易于使用,這讓我們覺得它幾乎是免費的。但 goroutines 確實會占用大量內(nèi)存,從而影響應(yīng)用程序性能。通常,Go 開發(fā)人員會在不計算或不知道何時退出的情況下創(chuàng)建無限的 goroutine。因此,建議您僅在知道 goroutine 何時退出時才啟動它。采用協(xié)程池來進(jìn)行管理,我們不再贅述如何創(chuàng)建一個協(xié)程池,其他章節(jié)中我們將重點介紹。

5. 使用無鎖算法

您應(yīng)該避免同步,因為它會導(dǎo)致競爭。為了提高延遲和效率,您應(yīng)該防止互斥。許多無鎖解決方案可用于一些常見的數(shù)據(jù)結(jié)構(gòu)。如果確實需要鎖,你首選的應(yīng)該為atomic,然后才為mutex。

6. 使用已編譯的正則表達(dá)式

有些程序可能會多次使用同一個正則表達(dá)式,如果在每次使用前都編譯正則表達(dá)式,應(yīng)用程序會很低效。因此,對于重復(fù)匹配,您應(yīng)該使用已編譯的正則表達(dá)式。 性能差距還是很明顯的,需要注意。

7.避免使用cgo

Go 程序可以通過使用 cgo 調(diào)用 C 庫。但是cgo函數(shù)的開銷很大,它在運行過程中會消耗線程,就像阻塞I/O一樣。您不應(yīng)該在緊密循環(huán)之間調(diào)用 C 代碼。為了 Golang 應(yīng)用程序的最佳性能,最好避免使用 cgo。后續(xù)的文章中我們將介紹如何優(yōu)化cgo的性能。(既然不得不用,那么將如何用好cgo)

8.不要在熱點分配內(nèi)存

當(dāng)您創(chuàng)建新對象時,系統(tǒng)會消耗內(nèi)存和 CPU 周期,從而增加延遲。它占用GC效率,所以頻繁創(chuàng)建對象可不是個好事情,尤其是在熱點地區(qū)。因此,只要有可能,您應(yīng)該重用對象,考慮sync.Pool

9.用好sync.RWMutex

同步的重對象的完全鎖定,goroutines 需要等待很長時間。因此在讀多寫少的場景中,優(yōu)先考慮sync.RWMutex

10. 在文本格式上使用二進(jìn)制 -

兩種二進(jìn)制文本格式在 PostgresSQL 中均有效。但是二進(jìn)制比文本格式快。使用二進(jìn)制形式時,僅在從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換時才需要處理。因此,對于 PostgresSQL 服務(wù)器,二進(jìn)制格式比文本格式的傳輸效率更高。

11. 利用緩沖 I/O-

訪問單個對象需要磁盤操作,這會破壞程序的效率。使用緩沖輸入/輸出將有效地提高您的應(yīng)用程序速度,它必須讀取和寫入更大的數(shù)據(jù)塊。

12. 更喜歡使用 StringBuffer 或 StringBuilder-

使用“+”和“+=”運算符,系統(tǒng)在每次賦值時分配一個新字符串。為了克服這種低效率,您應(yīng)該使用 StringBuffer 和 StringBuilder 來快速執(zhí)行您的程序。具體見我另一篇文章:再論Golang字符串拼接問題

13. 選擇 Protocol Buffers 和 MessagePack

避免使用官方提供的Gob 和 JSON 作為序列化反序列化方案,因為它們使用了反射,實現(xiàn)的方式相當(dāng)丑陋。我們推薦應(yīng)該使用 Protocol Buffers 和 MessagePack作為二進(jìn)制的序列化方案,當(dāng)然你非要用json序列化和反序列化,我們給出社區(qū)中給出的兩種技術(shù)方案,都對JSON的操作進(jìn)行性能上的優(yōu)化。

1.sonic

sonic 是字節(jié)跳動開源的一款 Golang JSON 庫,基于即時編譯(Just-In-Time Compilation)與向量化編程(Single Instruction Multiple Data)技術(shù),大幅提升了 Go 程序的 JSON 編解碼性能。同時結(jié)合 lazy-load 設(shè)計思想,它也為不同業(yè)務(wù)場景打造了一套全面高效的 API。自 2021 年 7 月份發(fā)布以來, sonic 已被抖音、今日頭條等業(yè)務(wù)采用,累計為字節(jié)跳動節(jié)省了數(shù)十萬 CPU 核。

項目地址:sonic

2.go-json

go-json與其他庫相比,在編碼和解碼方面都非常快。 通過使用自動代碼生成來提高性能或使用專用接口,它更容易實現(xiàn),但敢于堅持與 并且是簡單接口的兼容性。另外它高度兼容系統(tǒng)json庫,所以你可以快速在你的項目中進(jìn)行替換使用。它采用對象池,避免反射等手段進(jìn)行優(yōu)化,以后的章節(jié)中我們將重點介紹反射的優(yōu)化技術(shù)。

14.預(yù)分配切片

當(dāng)您的需求達(dá)到其當(dāng)前容量時,Golang 會自動分配內(nèi)存。在重新分配期間,系統(tǒng)會在數(shù)據(jù)移動到新位置時新的內(nèi)存。為了避免這種內(nèi)存浪費和不必要的垃圾收集,您應(yīng)該盡可能預(yù)分配足夠的使用內(nèi)存。切片不是List,所以不要以為 var s =[]int={},以后直接append就好了,因為不斷的擴容會帶來無窮的性能損害。

15. 對map能使用 int就別string

如果您的應(yīng)用程序使用map,那么您應(yīng)該在可以使用int作為key時就不要用string作為key。

四、總結(jié)

可靠性和應(yīng)用程序性能都很重要。永遠(yuǎn)記住,應(yīng)用程序性能速度是以毫不費力、開發(fā)時間和持續(xù)維護為代價的。如果您要構(gòu)建 Golang 應(yīng)用程序,了解上述提高 Golang 應(yīng)用程序性能的提示和技巧將有助于您進(jìn)行有效的應(yīng)用程序開發(fā)。

以上就是Golang應(yīng)用程序性能優(yōu)化技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Golang程序性能優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang有類型常量和無類型常量的區(qū)別

    Golang有類型常量和無類型常量的區(qū)別

    本文主要介紹了Golang有類型常量和無類型常量的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • gorm update傳入struct對象,零值字段不更新的解決方案

    gorm update傳入struct對象,零值字段不更新的解決方案

    這篇文章主要介紹了gorm update傳入struct對象,零值字段不更新的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 一文初探Go語言中的reflect反射包

    一文初探Go語言中的reflect反射包

    這篇文章主要和大家分享一下Go語言中的reflect反射包,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,需要的小伙伴可以參考一下
    2022-12-12
  • Go語言kafka生產(chǎn)消費消息實例搬磚

    Go語言kafka生產(chǎn)消費消息實例搬磚

    這篇文章主要為大家介紹了Go語言kafka生產(chǎn)消費消息的實例搬磚,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • gomod包依賴管理工具使用詳解

    gomod包依賴管理工具使用詳解

    這篇文章主要為大家介紹了gomod如何解決包管理問題使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Golang語言如何高效拼接字符串詳解

    Golang語言如何高效拼接字符串詳解

    最近在做性能優(yōu)化,有個函數(shù)里面的耗時特別長,看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其實有很多種實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang語言如何高效拼接字符串的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 解決Goland 同一個package中函數(shù)互相調(diào)用的問題

    解決Goland 同一個package中函數(shù)互相調(diào)用的問題

    這篇文章主要介紹了解決Goland 同一個package中函數(shù)互相調(diào)用的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go實現(xiàn)map轉(zhuǎn)json的示例詳解

    Go實現(xiàn)map轉(zhuǎn)json的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實現(xiàn)map轉(zhuǎn)json的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • golang?gorm更新日志執(zhí)行SQL示例詳解

    golang?gorm更新日志執(zhí)行SQL示例詳解

    這篇文章主要為大家介紹了golang?gorm更新日志執(zhí)行SQL示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray詳解

    golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray詳解

    這篇文章主要介紹了golang數(shù)據(jù)結(jié)構(gòu)之golang稀疏數(shù)組sparsearray的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09

最新評論