Golang如何快速刪除map所有元素
1. 所有Go版本通用方法
重新申請(qǐng)一個(gè)新的map,舊的map交給GC去回收。
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方法刪除。
這個(gè)函數(shù)并沒有顯示的調(diào)用方法,當(dāng)你使用for循環(huán)遍歷刪除所有元素時(shí),Go的編譯器會(huì)優(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) } }
把上述源代碼直接編譯成匯編(默認(rèn)編譯是會(huì)優(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)化選項(xiàng)后,Go編譯器直接通過循環(huán)遍歷來刪除map里面的元素。
由上可知,遍歷刪除在經(jīng)過編譯器優(yōu)化后會(huì)調(diào)用mapclear一次性刪除map所有元素,那這個(gè)mapclear函數(shù)是如何實(shí)現(xiàn)的,效率如何?
mapclear源碼實(shí)現(xiàn)
這部分代碼涉及到內(nèi)存管理和GC,只能看懂個(gè)大概,后續(xù)再補(bǔ)充。
實(shí)現(xiàn)思路
- 清空統(tǒng)計(jì)數(shù)據(jù),如元素個(gè)數(shù)、溢出數(shù)等。
- 重新申請(qǐng)一個(gè)新的extra,原有的extra交給GC。
- 釋放桶內(nèi)存塊。
func mapclear(t *maptype, h *hmap) { ... // 把oldbuckets置nil,如果有oldbuckets就讓GC處理 h.oldbuckets = nil // 初始化溢出數(shù)、元素個(gè)數(shù) h.nevacuate = 0 h.noverflow = 0 h.count = 0 // 重新申請(qǐng)一個(gè)新的extra,舊的交給GC回收 if h.extra != nil { *h.extra = mapextra{} } // 清空bucket _, nextOverflow := makeBucketArray(t, h.B, h.buckets) ... } func makeBucketArray(t *maptype, b uint8, dirtyalloc unsafe.Pointer) (buckets unsafe.Pointer, nextOverflow *bmap) { base := bucketShift(b) nbuckets := base ... // 沒有分配過內(nèi)存,則申請(qǐng)一個(gè)新的 if dirtyalloc == nil { buckets = newarray(t.bucket, int(nbuckets)) } else { // 直接釋放整個(gè)buckets buckets = dirtyalloc size := t.bucket.size * nbuckets if t.bucket.kind&kindNoPointers == 0 { memclrHasPointers(buckets, size) } else { memclrNoHeapPointers(buckets, size) } } ... }
總結(jié)
使用mapclear方法清空map時(shí),做的工作就是初始化和釋放申請(qǐng)內(nèi)存塊,效率很高。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Golang使用Gin框架實(shí)現(xiàn)http分塊傳輸
這篇文章主要為大家詳細(xì)介紹了Golang中如何使用Gin框架實(shí)現(xiàn)http分塊傳輸功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以參考一下2023-05-05一文理解Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn)
本文主要介紹了Goland協(xié)程調(diào)度器scheduler的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息
反射是通過實(shí)體對(duì)象獲取反射對(duì)象(Value、Type),然后可以操作相應(yīng)的方法。本文將利用Go語言中的反射reflect實(shí)現(xiàn)獲取接口變量信息,需要的可以參考一下2022-05-05