map性能對(duì)比

// 對(duì)外暴露的map
type MutexMap struct {
    items map[string]interface{} // 為了和上面的ConcurrentMap做比較,都采用string->interface的方式
    mu    *sync.RWMutex          // 讀寫(xiě)鎖
}

// 新建一個(gè)map
func NewMutexMap() *MutexMap {
    return &MutexMap{
        items: map[string]interface{}{},
        mu:    new(sync.RWMutex),
    }
}

// Set 設(shè)置key,value
func (m MutexMap) Set(key string, value interface{}) {
    m.mu.Lock()          // 加鎖(全鎖定)
    m.items[key] = value // 賦值
    m.mu.Unlock()        // 解鎖
}

// Get 獲取key對(duì)應(yīng)的value
func (m MutexMap) Get(key string) (value interface{}, ok bool) {
    m.mu.RLock()             // 加鎖(讀鎖定)
    value, ok = m.items[key] // 取值
    m.mu.RUnlock()           // 解鎖
    return value, ok
}

// Count 統(tǒng)計(jì)key個(gè)數(shù)
func (m MutexMap) Count() int {
    m.mu.RLock() // 加鎖(讀鎖定)
    count := len(m.items)
    m.mu.RUnlock() // 解鎖
    return count
}

// Keys 所有的key
func (m MutexMap) Keys() []string {
    m.mu.RLock() // 加鎖(讀鎖定)
    keys := make([]string, len(m.items))
    for k := range m.items {
        keys = append(keys, k)
    }
    m.mu.RUnlock() // 解鎖

    return keys
}

sync.map 、MutexMap 、ConcurrentMap性能對(duì)比

package main

import (
    "math/rand"
    "strconv"
    "sync"
    "testing"
)

// 10萬(wàn)次的賦值,10萬(wàn)次的讀取
var times int = 100000

// 測(cè)試ConcurrentMap
func BenchmarkTestConcurrentMap(b *testing.B) {
    for k := 0; k < b.N; k++ {
        b.StopTimer()
        // 產(chǎn)生10000個(gè)不重復(fù)的鍵值對(duì)(string -> int)
        testKV := map[string]int{}
        for i := 0; i < 10000; i++ {
            testKV[strconv.Itoa(i)] = i
        }

        // 新建一個(gè)ConcurrentMap
        pMap := NewConcurrentMap()

        // set到map中
        for k, v := range testKV {
            pMap.Set(k, v)
        }

        // 開(kāi)始計(jì)時(shí)
        b.StartTimer()

        wg := sync.WaitGroup{}
        wg.Add(2)

        // 賦值
        go func() {
            // 對(duì)隨機(jī)key,賦值times次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Set(strconv.Itoa(index), index+1)
            }
            wg.Done()
        }()

        // 讀取
        go func() {
            // 對(duì)隨機(jī)key,讀取times次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Get(strconv.Itoa(index))
            }
            wg.Done()
        }()

        // 等待兩個(gè)協(xié)程處理完畢
        wg.Wait()
    }
}

// 測(cè)試map加鎖
func BenchmarkTestMap(b *testing.B) {
    for k := 0; k < b.N; k++ {
        b.StopTimer()
        // 產(chǎn)生10000個(gè)不重復(fù)的鍵值對(duì)(string -> int)
        testKV := map[string]int{}
        for i := 0; i < 10000; i++ {
            testKV[strconv.Itoa(i)] = i
        }

        // 新建一個(gè)MutexMap
        pMap := NewMutexMap()

        // set到map中
        for k, v := range testKV {
            pMap.Set(k, v)
        }

        // 開(kāi)始計(jì)時(shí)
        b.StartTimer()

        wg := sync.WaitGroup{}
        wg.Add(2)
        // 賦值
        go func() {
            // 對(duì)隨機(jī)key,賦值100萬(wàn)次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Set(strconv.Itoa(index), index+1)
            }
            wg.Done()
        }()

        // 讀取
        go func() {
            // 對(duì)隨機(jī)key,讀取100萬(wàn)次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Get(strconv.Itoa(index))
            }
            wg.Done()
        }()

        // 等待兩個(gè)協(xié)程處理完畢
        wg.Wait()
    }
}

// 測(cè)試sync.map
func BenchmarkTestSyncMap(b *testing.B) {
    for k := 0; k < b.N; k++ {
        b.StopTimer()
        // 產(chǎn)生10000個(gè)不重復(fù)的鍵值對(duì)(string -> int)
        testKV := map[string]int{}
        for i := 0; i < 10000; i++ {
            testKV[strconv.Itoa(i)] = i
        }

        // 新建一個(gè)sync.Map
        pMap := &sync.Map{}

        // set到map中
        for k, v := range testKV {
            pMap.Store(k, v)
        }

        // 開(kāi)始計(jì)時(shí)
        b.StartTimer()

        wg := sync.WaitGroup{}
        wg.Add(2)

        // 賦值
        go func() {
            // 對(duì)隨機(jī)key,賦值10萬(wàn)次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Store(strconv.Itoa(index), index+1)
            }
            wg.Done()
        }()

        // 讀取
        go func() {
            // 對(duì)隨機(jī)key,讀取10萬(wàn)次
            for i := 0; i < times; i++ {
                index := rand.Intn(times)
                pMap.Load(strconv.Itoa(index))
            }
            wg.Done()
        }()

        // 等待兩個(gè)協(xié)程處理完畢
        wg.Wait()
    }
}

執(zhí)行命令:go test -bench=.

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容