亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang應用程序性能優化技巧有哪些

發布時間:2023-04-11 15:43:24 來源:億速云 閱讀:113 作者:iii 欄目:開發技術

這篇文章主要講解了“Golang應用程序性能優化技巧有哪些”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Golang應用程序性能優化技巧有哪些”吧!

    一、概述

    隨著科技的進步,人人都想要快速的應用,用戶想要快速的交付,開發者想要快速的性能,創業者想要兩者兼而有之。這就需要優化您的應用程序性能。您需要提高應用程序的速度和性能,使其成為市場上最好的。您想要優化 Golang 應用程序的主要原因有兩個——資源效率和改善操作延遲。您的應用程序的最終目標應該是它不需要太多資源而繼續等待操作。盡管您的 Golang 應用程序太復雜以至于無法執行其中一項任務,但它必須依賴另一項任務,這樣一來,它就變成了一個死循環的依賴項。

    二、關于性能優化的方向

    延遲問題

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

    資源效率

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

    算法效率

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

    三、提高 Golang 應用程序性能的最佳實踐

    1. 并行化 CPU 工作

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

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

    //非并行版本

    package main
    
    import (
    	"fmt"
    	"io/ioutil"
    	"log"
    	"path/filepath"
    	"time"
    )
    
    const (
    	//目標目錄
    	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
    	//文件數目
    	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)
    }
    
    //-------------結果---------------
    
    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{}{} //限制并發量
    	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
    	//文件數目
    	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)
    }
    //-------------結果---------------
    used time: 7.3528287s
    total size: 8.5GB 
    file count: 416088

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

    2.觀察你的超時

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

    3. 使 I/O 操作異步

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

    4.減少Goroutines的使用

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

    5. 使用無鎖算法

    您應該避免同步,因為它會導致競爭。為了提高延遲和效率,您應該防止互斥。許多無鎖解決方案可用于一些常見的數據結構。如果確實需要鎖,你首選的應該為atomic,然后才為mutex。

    6. 使用已編譯的正則表達式

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

    7.避免使用cgo

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

    8.不要在熱點分配內存

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

    9.用好sync.RWMutex

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

    10. 在文本格式上使用二進制 -

    兩種二進制文本格式在 PostgresSQL 中均有效。但是二進制比文本格式快。使用二進制形式時,僅在從網絡字節序轉換時才需要處理。因此,對于 PostgresSQL 服務器,二進制格式比文本格式的傳輸效率更高。

    11. 利用緩沖 I/O-

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

    12. 更喜歡使用 StringBuffer 或 StringBuilder-

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

    13. 選擇 Protocol Buffers 和 MessagePack

    避免使用官方提供的Gob 和 JSON 作為序列化反序列化方案,因為它們使用了反射,實現的方式相當丑陋。我們推薦應該使用 Protocol Buffers 和 MessagePack作為二進制的序列化方案,當然你非要用json序列化和反序列化,我們給出社區中給出的兩種技術方案,都對JSON的操作進行性能上的優化。

    1.sonic

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

    項目地址:sonic

    Golang應用程序性能優化技巧有哪些

    2.go-json

    go-json與其他庫相比,在編碼和解碼方面都非常快。 通過使用自動代碼生成來提高性能或使用專用接口,它更容易實現,但敢于堅持與 并且是簡單接口的兼容性。另外它高度兼容系統json庫,所以你可以快速在你的項目中進行替換使用。它采用對象池,避免反射等手段進行優化。

    Golang應用程序性能優化技巧有哪些

    14.預分配切片

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

    15. 對map能使用 int就別string

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

    感謝各位的閱讀,以上就是“Golang應用程序性能優化技巧有哪些”的內容了,經過本文的學習后,相信大家對Golang應用程序性能優化技巧有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    铜川市| 宁南县| 山阳县| 如皋市| 竹溪县| 隆子县| 岳西县| 织金县| 铁岭市| 耿马| 舞阳县| 明星| 博兴县| 喜德县| 根河市| 江门市| 金川县| 中卫市| 枣强县| 建宁县| 秭归县| 永福县| 临清市| 台东市| 论坛| 墨玉县| 莫力| 高阳县| 颍上县| 奉节县| 鄂尔多斯市| 平远县| 瑞丽市| 岑溪市| 应城市| 义乌市| 伊金霍洛旗| 且末县| 织金县| 穆棱市| 铁力市|