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

golang?對(duì)象深拷貝的常見方式及性能

 更新時(shí)間:2022年06月20日 08:22:30   作者:??whoops本尊????  
這篇文章主要介紹了golang?對(duì)象深拷貝的常見方式及性能,Go語言中所有賦值操作都是值傳遞,如果結(jié)構(gòu)中不含指針,則直接賦值就是深度拷貝,文章圍繞主題展開更多相關(guān)資料,需要的小伙伴可以參考一下

關(guān)于golang拷貝的概念

Go語言中所有賦值操作都是值傳遞,如果結(jié)構(gòu)中不含指針,則直接賦值就是深度拷貝;如果結(jié)構(gòu)中含有指針(包括自定義指針,以及切片,map等使用了指針的內(nèi)置類型),則數(shù)據(jù)源和拷貝之間對(duì)應(yīng)指針會(huì)共同指向同一塊內(nèi)存,這時(shí)深度拷貝需要特別處理。目前,有三種方法,一是用gob序列化成字節(jié)序列再反序列化生成克隆對(duì)象;二是先轉(zhuǎn)換成json字節(jié)序列,再解析字節(jié)序列生成克隆對(duì)象;三是針對(duì)具體情況,定制化拷貝。前兩種方法雖然比較通用但是因?yàn)槭褂昧藃eflex反射,性能比定制化拷貝要低出2個(gè)數(shù)量級(jí),所以在性能要求較高的情況下應(yīng)該盡量避免使用前兩者。

完整代碼

package json
import (
   "bytes"
   "encoding/gob"
   "encoding/json"
   "fmt"
   "testing"
)
/**
 * @Description: 請(qǐng)求信息
 */
type BidRequest struct {
   ID     string  `json:"id"`
   Imp    []*Imp  `json:"imp"`
   Device *Device `json:"device"`
}
/**
 * @Description: imp對(duì)象
 */
type Imp struct {
   ID          string  `json:"id"`
   Tagid       string  `json:"tagid"`
   Bidfloor    float64 `json:"bidfloor"`
}
/**
 * @Description: 設(shè)備信息
 */
type Device struct {
   Ua         string `json:"ua"`
   IP         string `json:"ip"`
   Geo        *Geo   `json:"geo"`
   Make       string `json:"make"`
   Model      string `json:"model"`
   Os         string `json:"os"`
   Osv        string `json:"osv"`
}
/**
 * @Description: 地理位置信息
 */
type Geo struct {
   Lat     int    `json:"lat"`
   Lon     int    `json:"lon"`
   Country string `json:"country"`
   Region  string `json:"region"`
   City    string `json:"city"`
}
/**
 * @Description: 利用gob進(jìn)行深拷貝
 */
func DeepCopyByGob(src,dst interface{}) error {
   var buffer bytes.Buffer
   if err := gob.NewEncoder(&buffer).Encode(src); err != nil {
      return err
   }
   return gob.NewDecoder(&buffer).Decode(dst)
}
/**
 * @Description: 利用json進(jìn)行深拷貝
 */
func DeepCopyByJson(src,dst *BidRequest) error{
   if tmp, err := json.Marshal(&src);err!=nil{
      return err
   }else {
      err = json.Unmarshal(tmp, dst)
      return err
   }
}

/**
 * @Description: 通過自定義進(jìn)行copy
 */
func DeepCopyByCustom(src,dst *BidRequest){
   dst.ID=src.ID
   dst.Device=&Device{
      Ua: src.Device.Ua,
      IP: src.Device.IP,
      Geo: &Geo{
         Lat: src.Device.Geo.Lat,
         Lon: src.Device.Geo.Lon,
      },
      Make: src.Device.Make,
      Model: src.Device.Model,
      Os: src.Device.Os,
      Osv: src.Device.Osv,
   }
   dst.Imp=make([]*Imp,len(src.Imp))
   for index,imp:=range src.Imp{
      //注意此處因?yàn)閕mp對(duì)象里無指針對(duì)象,所以可以直接使用等于
      dst.Imp[index]=imp
   }
}

func initData()*BidRequest  {
   str:="{"id":"MM7dIXz4H05qtmViqnY5dW","imp":[{"id":"1","tagid":"3979722720","bidfloor":0.01}],"device":{"ua":"Mozilla/5.0 (Linux; Android 10; SM-G960N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.115 Mobile Safari/537.36 (Mobile; afma-sdk-a-v212621039.212621039.0)","ip":"192.168.1.0","geo":{"lat":0,"lon":0,"country":"KOR","region":"KR-11","city":"Seoul"},"make":"samsung","model":"sm-g960n","os":"android","osv":"10"}}"
   ans:=new(BidRequest)
   json.Unmarshal([]byte(str),&ans)
   return ans
}

/**
 * @Description: 壓測(cè)深拷貝 -gob
 */
func BenchmarkDeepCopy_Gob(b *testing.B)  {
   src:=initData()
   b.ResetTimer()
   for i:=0;i<b.N;i++{
      DeepCopyByGob(src,new(BidRequest))
   }
}

/**
 * @Description: 壓測(cè)深拷貝 -json
 */
func BenchmarkDeepCopy_Json(b *testing.B)  {
   src:=initData()
   b.ResetTimer()
   for i:=0;i<b.N;i++{
      DeepCopyByJson(src,new(BidRequest))
   }
}
/**
 * @Description: 壓測(cè)深拷貝 -custom
 */
func BenchmarkDeepCopy_custom(b *testing.B)  {
   src:=initData()
   b.ResetTimer()
   for i:=0;i<b.N;i++{
      DeepCopyByCustom(src,new(BidRequest))
   }
}
/**
 * @Description: 測(cè)試拷貝是否ok
 */
func TestCpoyIsOk(t *testing.T)  {
   src:=initData()
   //1.gob
   dst01:=new(BidRequest)
   DeepCopyByGob(src,dst01)
   bs01, _ := json.Marshal(dst01)
   fmt.Printf("%v\n",string(bs01))
   //2.json
   dst02:=new(BidRequest)
   DeepCopyByJson(src,dst02)
   bs02, _ := json.Marshal(dst02)
   fmt.Printf("%v\n",string(bs02))
   //3.custom
   dst03:=new(BidRequest)
   DeepCopyByCustom(src,dst03)
   bs03, _ := json.Marshal(dst02)
   fmt.Printf("%v\n",string(bs03))
}

先執(zhí)行 TestCpoyIsOk,驗(yàn)證三種方式的輸出是否ok,其驗(yàn)證結(jié)果如下:

benmark三種copy方式:

執(zhí)行命令 go test -bench=. -benchmem 可以同時(shí)查看到每次操作的內(nèi)存和耗時(shí)的情況

總結(jié)

可以看到 從性能上來講 custom>json>gob,從代碼數(shù)量上來講 gob>json>custom ,因此具體使用時(shí)應(yīng)該充分考慮性能和代碼復(fù)雜度,若性能要求不是很高建議gob方法,其比較簡(jiǎn)潔并且利于生成工具包,若要求性能則盡量使用custom,此處不偷懶可以提高性能哦。若是性能要求在中間,則可以使用json先序列化,再反序列化賦值。

到此這篇關(guān)于golang 對(duì)象深拷貝的常見方式及性能的文章就介紹到這了,更多相關(guān)golang 深拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang讀取yaml文件的示例代碼

    golang讀取yaml文件的示例代碼

    本文主要介紹了golang讀取yaml文件的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • Go語言如何獲取goroutine的id

    Go語言如何獲取goroutine的id

    在Go語言中,獲取?goroutine的id并不像其他編程語言那樣容易,但依然有辦法,這篇文章就來和大家聊聊具體實(shí)現(xiàn)的方法,感興趣的小伙伴可以了解下
    2024-12-12
  • go語言中基本數(shù)據(jù)類型及應(yīng)用快速了解

    go語言中基本數(shù)據(jù)類型及應(yīng)用快速了解

    這篇文章主要為大家介紹了go語言中基本數(shù)據(jù)類型應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • golang實(shí)現(xiàn)http server提供文件下載功能

    golang實(shí)現(xiàn)http server提供文件下載功能

    這篇文章主要介紹了golang實(shí)現(xiàn)http server提供文件下載功能,本文給大家簡(jiǎn)單介紹了Golang的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • sublime text3解決Gosublime無法自動(dòng)補(bǔ)全代碼的問題

    sublime text3解決Gosublime無法自動(dòng)補(bǔ)全代碼的問題

    本文主要介紹了sublime text3解決Gosublime無法自動(dòng)補(bǔ)全代碼的問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 詳解Go語言中接口應(yīng)用模式或慣例介紹

    詳解Go語言中接口應(yīng)用模式或慣例介紹

    這篇文章主要為大家詳細(xì)介紹了Go語言中接口應(yīng)用模式或慣例介紹的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • go-micro微服務(wù)JWT跨域認(rèn)證問題

    go-micro微服務(wù)JWT跨域認(rèn)證問題

    JWT 以 JSON 對(duì)象的形式安全傳遞信息。因?yàn)榇嬖跀?shù)字簽名,因此所傳遞的信息是安全的,這篇文章主要介紹了go-micro微服務(wù)JWT跨域認(rèn)證,需要的朋友可以參考下
    2023-01-01
  • Go語言使用字符串的幾個(gè)技巧分享

    Go語言使用字符串的幾個(gè)技巧分享

    這篇文章中小編將給出一些Go語言在處理字符串方面的技巧,對(duì)大家學(xué)習(xí)Go語言具有一定的參考借鑒價(jià)值,下面一起看看吧。
    2016-09-09
  • golangci-lint安裝與Goland集成問題

    golangci-lint安裝與Goland集成問題

    這篇文章主要介紹了golangci-lint安裝與Goland集成,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • golang gin 監(jiān)聽rabbitmq隊(duì)列無限消費(fèi)的案例代碼

    golang gin 監(jiān)聽rabbitmq隊(duì)列無限消費(fèi)的案例代碼

    這篇文章主要介紹了golang gin 監(jiān)聽rabbitmq隊(duì)列無限消費(fèi),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12

最新評(píng)論

大宁县| 湘潭县| 茂名市| 铜鼓县| 新竹县| 喀喇| 尼勒克县| 新营市| 普定县| 三穗县| 赫章县| 蒲江县| 阳原县| 咸阳市| 孟村| 澜沧| 文登市| 南通市| 和龙市| 涞源县| 甘孜县| 合川市| 阜康市| 鹰潭市| 静海县| 南乐县| 祁阳县| 张家港市| 鄂托克前旗| 广平县| 渝北区| 桂阳县| 嘉禾县| 康乐县| 平昌县| 阜新| 东光县| 招远市| 福海县| 宁晋县| 湘潭市|