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

有没有办法分配映射的内存,该映射最多具有Nmax指向最大长度切片的键Nmax

我目前只是通过 指定最大键数make(map[int][]int,Nmax),但我不确定如何告诉 Go 每个切片都是最大长度,Nmax因为我不知道键是先验的。

我基本上有一堆人口为整数的网站。我使用地图来跟踪有多少站点具有给定的人口N。我的程序中的瓶颈似乎是 runtime.memmove,我猜这是由于不断调整地图指向的切片的大小。


千巷猫影
浏览 63回答 2
2回答

繁星coding

因此,鉴于您对问题的描述确实相当模糊,我将首先说明我将如何“管理”地图。为了简单起见,我将把所有逻辑包装在接收器函数中,因此将映射包装在自定义类型中: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 keyfunc (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 typefunc (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))) // 4fmt.Println(cap(myData.Get(4))) // 10// nil-values are filtered outmyData.Set(4, 5, 6, 7, 0, 0, 0, 0)fmt.Println(len(myData.Get(4))) // 7fmt.Println(cap(myData.Get(4))) // 10// exceeding capacity of 10fmt.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?}

MM们

您对问题的描述含糊不清,您没有提供代码来说明您的问题。如果地图切片容量等于零,则将其设置为Nmax。例如,package mainimport "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]]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go