最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang并發(fā)之使用sync.Pool優(yōu)化性能

 更新時(shí)間:2023年10月24日 09:30:04   作者:jefffff  
在Go提供如何實(shí)現(xiàn)對(duì)象的緩存池功能,常用一種實(shí)現(xiàn)方式是sync.Pool,?其旨在緩存已分配但未使用的項(xiàng)目以供以后重用,從而減輕垃圾收集器(GC)的壓力,下面我們就來看看具體操作吧

簡介

在Go提供如何實(shí)現(xiàn)對(duì)象的緩存池功能?常用一種實(shí)現(xiàn)方式是:sync.Pool, 其旨在緩存已分配但未使用的項(xiàng)目以供以后重用,從而減輕垃圾收集器(GC)的壓力。

快速使用

sync.Pool的結(jié)構(gòu)也比較簡單,常用的方法有Get、Put

type Pool struct {
    local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
    localSize uintptr        // size of the local array

    victim     unsafe.Pointer // local from previous cycle
    victimSize uintptr        // size of victims array

    // New optionally specifies a function to generate
    // a value when Get would otherwise return nil.
    // It may not be changed concurrently with calls to Get.
    New func() any
}
func (p *Pool) Get() any  
func (p *Pool) Put(x any) 

接著,通過一個(gè)簡單的例子,來看看是如何使用的

package main

import (
    "fmt"
    "sync"
)

type Object struct {
    ID int
    // ...
}

func main() {
    // 1.創(chuàng)建一個(gè)sync.Pool對(duì)象
    pool := &sync.Pool{
       New: func() interface{} {
          fmt.Println("Creating a new object")
          return &Object{}
       },
    }
    // 2.pool.Get()方法從池中獲取一個(gè)對(duì)象。如果池中有可用的對(duì)象,Get()方法將返回其中一個(gè);否則,它將返回一個(gè)新創(chuàng)建的對(duì)象
    obj := pool.Get().(*Object)
    // 3.操作對(duì)象
    obj.ID = 1
    // 4.調(diào)用pool.Put()方法將對(duì)象放回池中
    pool.Put(obj)
    objBar := pool.Get().(*Object)
    fmt.Println("Object ID:", objBar.ID)
}

實(shí)踐應(yīng)用

在之前的文章中有提到的享元模式設(shè)計(jì)模式:flyweight(享元)的在棋牌游戲的應(yīng)用的案例。今天我們使用sync.Pool對(duì)該方案進(jìn)行優(yōu)化。 觀察在棋牌游戲的代碼,雖然解決了每次都要New一個(gè)對(duì)象的問題,但還存在幾個(gè)優(yōu)化點(diǎn):

  • 不能只能緩存特定的棋牌室類型對(duì)象;
  • 并發(fā)安全問題

原來是通過Factory工廠+Map實(shí)現(xiàn)享元模式,截取其中部分代碼如下

package design_mode

import "fmt"

var chessPieceUnit = map[int]*ChessPiece{
	1: {
		Name:  "車",
		Color: "紅",
		PositionX: 1,
		PositionY: 11,
	},
	2: {
		Name:  "馬",
		Color: "黑",
		PositionX: 2,
		PositionY: 2,
	},
	// 其他棋子
}

func NewChessPieceUnitFactory() *ChessBoard {
	board := &ChessBoard{Cards: map[int]*ChessPiece{}}
	for id := range chessPieceUnit {
		board.Cards[id] = chessPieceUnit[id]
	}
	return board
}

1.重構(gòu)Factory

接著,我們同sync.Pool修改一下Factory的實(shí)現(xiàn):

pool := &sync.Pool{
    New: func() interface{} {
       fmt.Println("Creating a new object")
       return NewChessBoard()
    },
}

game1 := pool.Get().(*ChessBoard)
game2 := pool.Get().(*ChessBoard)
fmt.Println(game1)
fmt.Println(game2)
fmt.Println(game1.Cards[0] == game2.Cards[0]) 

2. 并發(fā)安全問題

2.1 修改模型

為了方便觀察,給每個(gè)房間(棋牌室)增加一個(gè)創(chuàng)建時(shí)間

type ChessBoard struct {
    Cards map[int]*ChessPiece
    Time  time.Time
} 

2.2 并發(fā)測試

啟動(dòng)多個(gè)goroutine進(jìn)行測試

func main() {
    pool := &sync.Pool{
       New: func() interface{} {
          fmt.Println("Creating a new object")
          return NewChessBoard()
       },
    }
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
       wg.Add(1)
       go func(id int) {
          defer wg.Done()
          obj := pool.Get().(*ChessBoard)
          obj.Time = time.Now()
          pool.Put(obj)
          fmt.Printf("Object ID: %v\n", obj.Time)
       }(i)
    }
    wg.Wait()
} 

輸出如下:

Creating a new object
Creating a new object
Object ID: 2023-10-22 15:41:50.309343 +0800 CST m=+0.003511901
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201
Object ID: 2023-10-22 15:41:50.3117423 +0800 CST m=+0.005911201

可見,在多個(gè)goroutine的并發(fā)情況下,是安全,另外可以觀察到,sync.Pool沒有一直【Creating a new object】去New很多棋牌室。

小結(jié)

sync.Pool是Go語言標(biāo)準(zhǔn)庫中的一個(gè)類型,它提供了對(duì)象的緩存池功能。它的主要用途是存儲(chǔ)那些可以被復(fù)用的臨時(shí)對(duì)象,以便在需要時(shí)快速獲取,而不是每次都進(jìn)行新的對(duì)象分配。且多個(gè) goroutine 同時(shí)使用 Pool 是安全的。

本文簡述了sync.Pool的基礎(chǔ)使用,以及了如何使用其對(duì)實(shí)踐棋牌室游戲的案例進(jìn)行優(yōu)化過程。

以上就是golang并發(fā)之使用sync.Pool優(yōu)化性能的詳細(xì)內(nèi)容,更多關(guān)于go sync.Pool的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言連接Oracle數(shù)據(jù)庫的方法

    Go語言連接Oracle數(shù)據(jù)庫的方法

    這篇文章主要介紹了Go語言連接Oracle數(shù)據(jù)庫的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Go  slog使用入門示例教程

    Go  slog使用入門示例教程

    slog是Go 1.21 引入的官方結(jié)構(gòu)化日志庫(Structured Logging),它結(jié)束了Go標(biāo)準(zhǔn)庫只有簡單log包的歷史,讓我們可以直接輸出JSON或 Key-Value 格式的日志,接下來通過本文介紹Go  slog使用入門教程,感興趣的朋友一起看看吧
    2026-02-02
  • 詳解Go 語言中的比較操作符

    詳解Go 語言中的比較操作符

    這篇文章專注于 6 個(gè)操作符,==,!=,<,<=,> 和 >=。我們將深入探討它們的語法和用法的細(xì)微差別,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-08-08
  • Go?mod?replace使用方法及常見問題分析

    Go?mod?replace使用方法及常見問題分析

    這篇文章主要為大家介紹了Go?mod?replace使用方法及常見問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • go 下載非標(biāo)準(zhǔn)庫包(部份包被墻了)到本地使用的方法

    go 下載非標(biāo)準(zhǔn)庫包(部份包被墻了)到本地使用的方法

    今天小編就為大家分享一篇go 下載非標(biāo)準(zhǔn)庫包(部份包被墻了)到本地使用的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • Golang中的sync包的WaitGroup操作

    Golang中的sync包的WaitGroup操作

    這篇文章主要介紹了Golang中的sync包的WaitGroup操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golang logrus 日志包及日志切割的實(shí)現(xiàn)

    Golang logrus 日志包及日志切割的實(shí)現(xiàn)

    這篇文章主要介紹了Golang logrus 日志包及日志切割的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • go語言make初始化的實(shí)現(xiàn)

    go語言make初始化的實(shí)現(xiàn)

    Go語言中的make函數(shù)用于初始化切片、映射和通道,本文就來介紹一下go語言make初始化的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • golang雙鏈表的實(shí)現(xiàn)代碼示例

    golang雙鏈表的實(shí)現(xiàn)代碼示例

    這篇文章主要介紹了golang雙鏈表的實(shí)現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Golang并發(fā)編程之main goroutine的創(chuàng)建與調(diào)度詳解

    Golang并發(fā)編程之main goroutine的創(chuàng)建與調(diào)度詳解

    這篇文章主要為大家詳細(xì)介紹了Golang并發(fā)編程中main goroutine的創(chuàng)建與調(diào)度,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03

最新評(píng)論

巢湖市| 东明县| 和顺县| 浑源县| 金沙县| 嘉荫县| 沐川县| 永寿县| 中宁县| 福海县| 木兰县| 临猗县| 彩票| 屯留县| 阜新市| 黎城县| 乌鲁木齐县| 博湖县| 耿马| 雅安市| 西充县| 泰安市| 屏东县| 西丰县| 合山市| 山东省| 曲周县| 祥云县| 寿光市| 乌兰县| 鸡东县| 丰顺县| 松溪县| 四川省| 镇宁| 牟定县| 延津县| 青岛市| 甘肃省| 涪陵区| 公安县|