亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何分配內存以映射指向golang中的切片

如何分配內存以映射指向golang中的切片

Go
千巷貓影 2023-04-17 15:22:03
有沒有辦法分配映射的內存,該映射最多具有Nmax指向最大長度切片的鍵Nmax?我目前只是通過 指定最大鍵數make(map[int][]int,Nmax),但我不確定如何告訴 Go 每個切片都是最大長度,Nmax因為我不知道鍵是先驗的。我基本上有一堆人口為整數的網站。我使用地圖來跟蹤有多少站點具有給定的人口N。我的程序中的瓶頸似乎是 runtime.memmove,我猜這是由于不斷調整地圖指向的切片的大小。
查看完整描述

2 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

因此,鑒于您對問題的描述確實相當模糊,我將首先說明我將如何“管理”地圖。為了簡單起見,我將把所有邏輯包裝在接收器函數中,因此將映射包裝在自定義類型中:


type dataMap struct {

    data map[int][]int

    nmax int

}


func New(Nmax int) *dataMap {

    return &dataMap{

        data: make(map[int][]int, Nmax),

        nmax: Nmax,

    }

}


// Get - return slice for given key

func (d dataMap) Get(k int) []int {

    s, ok := d.data[k]

    if !ok {

        return nil // optionally return error

    }

    return s

}


// Set - set/append values to a given key - this is not safe for concurrent use

// if that's needed, add a RWMutex to the type

func (d *dataMap) Set(k int, vals ...int) error {

    s, ok := d.data[k]

    if !ok {

        s = make([]int, 0, d.nmax) // allocate slice of given length

    }

    // optionally check for nil-values + ensure we're not exceeding the nmax

    checked := make([]int, 0, len(vals))

    for i := range vals {

        if vals[i] != 0 {

            checked = append(checked, vals[i])

        }

    }

    if len(s) + len(checked) > d.nmax {

        return errors.New("max capacity exceeded")

    }

    s = append(s, checked...) // append values

    d.data[k] = s // update map

    return nil

}

這減少了不必要的內存(重新)分配調用。它還確保我可以在 O(1) 操作中獲取映射中任何切片的長度,而不必擔心 nil 值:


myData := New(10)

fmt.Println(myData.Set(4, 1, 2, 3, 4))

fmt.Println(len(myData.Get(4))) // 4

fmt.Println(cap(myData.Get(4))) // 10

// nil-values are filtered out

myData.Set(4, 5, 6, 7, 0, 0, 0, 0)

fmt.Println(len(myData.Get(4))) // 7

fmt.Println(cap(myData.Get(4))) // 10

// exceeding capacity of 10

fmt.Println(myData.Set(4, 8, 9, 10, 11)) // max capacity exceeded

工作演示

您可以使用數組而不是切片來管理容量,但這確實需要您手動跟蹤要開始附加值的索引/偏移量。一般來說,你不要在 golang 中使用數組,以免在非常非常特殊的情況下。在這種情況下,我只會選擇帶有固定帽的切片。這樣做的好處是,例如,您可以擁有不同長度的切片。結果也很容易測試,因為像這樣的類型很適合用接口類型替換它


type DataContainer interface {

    Get(k int) []int

    Set(k int, vals ...int) error

    Declare(k, capacity int) error // error if k is already in use?

}


查看完整回答
反對 回復 2023-04-17
?
MM們

TA貢獻1886條經驗 獲得超2個贊

您對問題的描述含糊不清,您沒有提供代碼來說明您的問題。


如果地圖切片容量等于零,則將其設置為Nmax。例如,


package main


import "fmt"


func main() {

    Nmax := 42


    m := make(map[int][]int, Nmax)


    k, e := 7, 11

    v := m[k]

    if cap(v) == 0 {

        v = make([]int, 0, Nmax)

    }

    m[k] = append(v, e)


    v = m[k]

    fmt.Println(k, len(v), cap(v), v)


    fmt.Println(m)

}

游樂場: https: //play.golang.org/p/csoUCUvVDAp


輸出:


7 1 42 [11]

map[7:[11]]


查看完整回答
反對 回復 2023-04-17
  • 2 回答
  • 0 關注
  • 92 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號