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

Golang 空map和未初始化map的注意事項說明

 更新時間:2021年04月29日 10:03:33   作者:菌菇  
這篇文章主要介紹了Golang 空map和未初始化map的注意事項說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

可以對未初始化的map進行取值,但取出來的東西是空:

var m1 map[string]string
fmt.Println(m1["1"])

不能對未初始化的map進行賦值,這樣將會拋出一個異常:

panic: assignment to entry in nil map

var m1 map[string]string
m1["1"] = "1"

通過fmt打印map時,空map和nil map結(jié)果是一樣的,都為map[]。所以,這個時候別斷定map是空還是nil,而應該通過map == nil來判斷。

補充:Golang清空map的兩種方式及性能比拼

一、Golang中刪除map的方法

1、所有Go版本通用方法

a := make(map[string]int)
a["a"] = 1
a["b"] = 2
// clear all
a = make(map[string]int)

2. Go 1.11版本以上用法

通過Go的內(nèi)部函數(shù)mapclear方法刪除。這個函數(shù)并沒有顯示的調(diào)用方法,當你使用for循環(huán)遍歷刪除所有元素時,Go的編譯器會優(yōu)化成Go內(nèi)部函數(shù)mapclear。

package main
func main() {
        m := make(map[byte]int)
        m[1] = 1
        m[2] = 2
        for k := range m {
	        delete(m, k)
        }
}

把上述源代碼直接編譯成匯編(默認編譯是會優(yōu)化的):

go tool compile -S map_clear.go

可以看到編譯器把源碼9行的for循環(huán)直接優(yōu)化成了mapclear去刪除所有元素。如下:

在這里插入圖片描述

再來看看關(guān)閉優(yōu)化后的結(jié)果:

go tool compile -l -N -S map_clear.go

關(guān)閉優(yōu)化選項后,Go編譯器直接通過循環(huán)遍歷來刪除map里面的元素。

在這里插入圖片描述

具體的mapclear代碼可以在go源碼庫中runtime/map.go文件中看到,代碼如下:

// mapclear deletes all keys from a map.
func mapclear(t *maptype, h *hmap) {
	if raceenabled && h != nil {
		callerpc := getcallerpc()
		pc := funcPC(mapclear)
		racewritepc(unsafe.Pointer(h), callerpc, pc)
	}
	if h == nil || h.count == 0 {
		return
	}
	if h.flags&hashWriting != 0 {
		throw("concurrent map writes")
	}
	h.flags ^= hashWriting
	h.flags &^= sameSizeGrow
	h.oldbuckets = nil
	h.nevacuate = 0
	h.noverflow = 0
	h.count = 0
	// Keep the mapextra allocation but clear any extra information.
	if h.extra != nil {
		*h.extra = mapextra{}
	}
	// makeBucketArray clears the memory pointed to by h.buckets
	// and recovers any overflow buckets by generating them
	// as if h.buckets was newly alloced.
	_, nextOverflow := makeBucketArray(t, h.B, h.buckets)
	if nextOverflow != nil {
		// If overflow buckets are created then h.extra
		// will have been allocated during initial bucket creation.
		h.extra.nextOverflow = nextOverflow
	}
	if h.flags&hashWriting == 0 {
		throw("concurrent map writes")
	}
	h.flags &^= hashWriting
}

二、兩種清空map方式性能比較

1、先用benchmark的方式測一下兩種方式

benchmark代碼如下:

func BenchmarkMakeNewMap(b *testing.B) {
	tmpMap := make(map[string]string, 10000)
	for i := 0; i < b.N; i++ {
		for j := 0; j < 10000; j++ {
			tmpMap["tmp"+strconv.Itoa(j)] = "tmp"
		}
		tmpMap = make(map[string]string, 10000)
	}
}
func BenchmarkDeleteMap(b *testing.B) {
	tmpMap := make(map[string]string, 10000)
	for i := 0; i < b.N; i++ {
		for j := 0; j < 10000; j++ {
			tmpMap["tmp"+strconv.Itoa(j)] = "tmp"
		}
		for k := range tmpMap {
			delete(tmpMap, k)
		}
	}
}

得到測試結(jié)果如下:

在這里插入圖片描述

從測試結(jié)果上看,好像確實delete的方式效率更高,但是這個benchmark中總感覺沒有測試到真正清空map的地方,中間穿插著put map的操作,我們用方法2再測一下。

2、單個UT測一下兩種方式

UT代碼如下:

測試過程中禁用了gc,避免gc對運行時間和內(nèi)存產(chǎn)生干擾。

func TestMakeNewMap(t *testing.T) {
   debug.SetGCPercent(-1)
   var m runtime.MemStats
   tmpMap := make(map[string]string, 1000000)
   for j := 0; j < 1000000; j++ {
      tmpMap["tmp"+strconv.Itoa(j)] = "tmp"
   }
   start := time.Now()
   tmpMap = make(map[string]string, 1000000)
   fmt.Println(time.Since(start).Microseconds())
   runtime.ReadMemStats(&m)
   fmt.Printf("%d Kb\n", m.Alloc/1024)
}
func TestDeleteMap(t *testing.T) {
   debug.SetGCPercent(-1)
   var m runtime.MemStats
   tmpMap2 := make(map[string]string, 1000000)
   for j := 0; j < 1000000; j++ {
      tmpMap2["tmp"+strconv.Itoa(j)] = "tmp"
   }
   start := time.Now()
   for k := range tmpMap2 {
      delete(tmpMap2, k)
   }
   fmt.Println(time.Since(start).Microseconds())
   runtime.ReadMemStats(&m)
   fmt.Printf("%d Kb\n", m.Alloc/1024)
}

測試結(jié)果如下:

在這里插入圖片描述

從測試結(jié)果上看,好像確實是make方式的效率更低,而且內(nèi)存占用更多,但結(jié)果真的是這樣嗎?

我們把make方式的make map的大小改為0再試一下:

tmpMap = make(map[string]string)

得到如下結(jié)果,What?時間為0了,內(nèi)存消耗也跟delete的方式一樣:

在這里插入圖片描述

我們把make方式的make map的大小改為10000再試一下:

tmpMap = make(map[string]string, 10000)

結(jié)果如下:

在這里插入圖片描述

三、總結(jié)

通過上面的測試,可以得出結(jié)論:

1、在map的數(shù)量級在10w以內(nèi)的話,make方式會比delete方式速度更快,但是內(nèi)存會消耗更多一點。

2、如果map數(shù)量級大于10w的話,delete的速度會更快,且內(nèi)存消耗更少。

3、對于不再使用的map,直接使用make方式,長度為0清空更快。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • 如何基于Golang實現(xiàn)Kubernetes邊車模式

    如何基于Golang實現(xiàn)Kubernetes邊車模式

    本文介紹了如何基于Go實現(xiàn)Kubernetes Sidecar模式,并通過實際示例演示創(chuàng)建Golang實現(xiàn)的微服務服務、Docker 容器化以及在 Kubernetes 上的部署和管理,感興趣的朋友一起看看吧
    2024-08-08
  • 深入探究Go語言的錯誤策略與異常機制

    深入探究Go語言的錯誤策略與異常機制

    本文深入探討了Go語言的錯誤策略與異常機制,主要介紹了錯誤處理的重要性,以及Go語言中的錯誤類型和處理函數(shù),此外還討論了Go語言的異常機制,包括panic和recover函數(shù)的使用,需要的朋友可以參考下
    2024-02-02
  • golang 阻止主goroutine退出的操作

    golang 阻止主goroutine退出的操作

    這篇文章主要介紹了golang 阻止主goroutine退出的操作方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 詳解golang中bufio包的實現(xiàn)原理

    詳解golang中bufio包的實現(xiàn)原理

    這篇文章主要介紹了詳解golang中bufio包的實現(xiàn)原理,通過分析golang中bufio包的源碼,來了解為什么bufio能夠提高文件讀寫的效率和速度
    2018-01-01
  • go Antlr重構(gòu)腳本解釋器實現(xiàn)示例

    go Antlr重構(gòu)腳本解釋器實現(xiàn)示例

    這篇文章主要為大家介紹了go Antlr重構(gòu)腳本解釋器實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 深入解析Go語言中for循環(huán)的寫法

    深入解析Go語言中for循環(huán)的寫法

    這篇文章主要介紹了Go語言中for循環(huán)的寫法,是Golang入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • Golang中struct{}和struct{}{}的區(qū)別解析

    Golang中struct{}和struct{}{}的區(qū)別解析

    這篇文章主要介紹了Golang中struct{}和struct{}{}的區(qū)別,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Golang 如何判斷數(shù)組某個元素是否存在 (isset)

    Golang 如何判斷數(shù)組某個元素是否存在 (isset)

    這篇文章主要介紹了Golang 如何判斷數(shù)組某個元素是否存在 (isset),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go操作Kafka使用示例詳解

    go操作Kafka使用示例詳解

    這篇文章主要為大家介紹了go操作Kafka使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 使用Go語言開發(fā)自動化API測試工具詳解

    使用Go語言開發(fā)自動化API測試工具詳解

    這篇文章主要為大家詳細介紹了如何使用Go語言開發(fā)自動化API測試工具,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-03-03

最新評論

三河市| 迁安市| 和林格尔县| 乐东| 衡南县| 清苑县| 西安市| 扶绥县| 宜昌市| 普定县| 财经| 扶绥县| 乐东| 赤城县| 高州市| 襄垣县| 孙吴县| 洪雅县| 高台县| 大同县| 固镇县| 安溪县| 成武县| 隆昌县| 白银市| 元氏县| 林西县| 轮台县| 布尔津县| 冀州市| 曲麻莱县| 类乌齐县| 汪清县| 五寨县| 龙泉市| 佳木斯市| 六安市| 正定县| 比如县| 黄石市| 三河市|