- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
在我模拟多粒子进化的程序中,我有一个 map ,它采用键值 pop
(人口规模)并返回包含具有该人口的地点的 slice : myMap[pop][]int
.这些 slice 通常都很大。
在每个进化步骤中,我选择一个随机种群大小 RandomPop
。然后我想随机选择一个人口至少为 RandomPop
的网站。 sitechosen
用于更新我的人口结构,我利用第二张 map 有效地更新 myMap 键。我当前的(缓慢的)实现看起来像
func Evolve( ..., myMap map[int][]int ,...){
RandomPop = rand.Intn(rangeofpopulation)+1
for i:=RandPop,; i<rangeofpopulation;i++{
preallocatedslice=append(preallocatedslice,myMap[i]...)
}
randomindex:= rand.Intn(len(preallocatedslice))
sitechosen= preallocatedslice[randomindex]
UpdateFunction(site)
//reset preallocated slice
preallocatedslice=preallocatedslice[0:0]
}
这段代码(显然)在将值从映射复制到预分配 slice 时遇到了巨大的瓶颈,runtime.memmove 占用了我 87% 的 CPU 使用率。我想知道是否有一种 O(1) 方法可以随机选择 myMap 指示的 slice 并集中包含的条目,键值介于 0
和 RandomPop
之间?如果有人知道它们,我对允许您操作自定义哈希表的包持开放态度。建议不需要安全的并发
尝试了其他方法:我之前让我的 map 记录了所有值至少为 pop
的站点,但这占用了 >10GB 的内存并且很愚蠢。我尝试存储指向相关 slice 的指针以制作查找 slice ,但 go 禁止这样做。我可以总结每个 slice 的长度并基于此生成一个随机数,然后按长度遍历 myMap 中的 slice ,但这比仅保留我的人口的更新 cdf 并进行二进制搜索要慢得多在上面。二分搜索速度很快,但更新 cdf,即使手动完成,也是 O(n)。我真的希望滥用哈希表来加快随机选择和更新速度(如果可能的话)
我有一个模糊的想法是编造某种 map 的嵌套结构,指向它们的内容,也指向比他们的键小的 map 或其他东西。
最佳答案
我在查看您的代码时有一个问题。为什么必须将值从 map 复制到 slice ?我的意思是,我认为我正在遵循背后的逻辑......但我想知道是否有办法跳过这一步。
所以我们有:
func Evolve( ..., myMap map[int][]int ,...){
RandomPop = rand.Intn(rangeofpopulation)+1
for i:=RandPop,; i<rangeofpopulation;i++{
// slice of preselected `sites`. one of this will be 'siteChosen'
// we expect to have `n sites` on `preAllocatedSlice`
// where `n` is the amount of iterations,
// ie; n = rangeofpopulation - RandPop
preallocatedslice=append(preallocatedslice,myMap[i]...)
}
// Once we have a list of sites, we select `one`
// under a normal distribution every site ha a chance of 1/n to be selected.
randomindex:= rand.Intn(len(preallocatedslice))
sitechosen= preallocatedslice[randomindex]
UpdateFunction(site)
...
}
但是如果我们将其更改为:
func Evolve( ..., myMap map[int][]int ,...){
if len(myMap) == 0 {
// Nothing to do, print a log!
return
}
// This variable will hold our site chosen!
var siteChosen []int
// Our random population size is a value from 1 to rangeOfPopulation
randPopSize := rand.Intn(rangeOfPopulation) + 1
for i := randPopSize; i < rangeOfPopulation; i++ {
// We are going to pretend that the current candidate is the siteChosen
siteChosen = myMap[i]
// Now, instead of copying `myMap[i]` to preAllocatedSlice
// We will test if the current candidate is actually the 'siteChosen` here:
// We know that the chances for an specific site to be the chosen is 1/n,
// where n = rangeOfPopulation - randPopSize
n := float64(rangeOfPopulation - randPopSize)
// we roll the dice...
isTheChosenOne := rand.Float64() > 1/n
if isTheChosenOne {
// If the candidate is the Chosen site,
// then we don't need to iterate over all the other elements.
break
}
}
// here we know that `siteChosen` is a.- a selected candidate, or
// b.- the last element assigned in the loop
// (in the case that `isTheChosenOne` was always false [which is a probable scenario])
UpdateFunction(siteChosen)
...
}
另外,如果你想计算n
,或者在循环外计算1/n
。所以这个想法是在循环内测试候选人是否是 siteChosen,并避免将候选人复制到这个预选池。
关于go - 从 golang 中受限键范围内的映射生成的 slice 中随机选择元素。有 O(1) 的捷径吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52611168/
试图自学,但发现很难找到示例,我的大脑已经陷入了困境。非常不确定 3 和 4,需要帮助才能使 5 正常工作。 package main import "fmt" func main () {
我有一个 slice ,它由字符串类型的 slice 组成。我希望能够为这片 slice 的各个元素赋值,不一定按顺序。然后,稍后,我希望能够更改任何特定元素的值。我已经阅读了有关 slice 的相同
我正在尝试将整数 slice append 到由整数 slice 组成的 slice 。当我打印 slice 时,它按预期显示。但是,当我将 slice append 到一片 slice 时,内容会发
我读了go slice usage and internals和 Slice和 Effective go#slice但是没有像这样用 3 个数字 slice 的方法:slice[a:b:c] 例如这段
这个问题在这里已经有了答案: Are slices passed by value? (5 个答案) 关闭 8 个月前。 如果可能的话,我正在努力使我的代码更具性能以节省内存 我做了一些研究,但找不
我是 Golang 的新手。 当我尝试它时,出现编译错误: cannot use a.B (type []*C) as type []Z in field value 代码: package main
我有数据结构: type PosList []int type InvertedIndex struct { Capacity int Len int IndexList [
我在 Go 中使用矩阵乘法进行一些性能实验并遇到了一些意想不到的结果。 版本 1: func newMatrix(n int) [][]int { m := make([][]int, n)
文档涵盖了 slice() 的 3 种用法对象: obj[:stop] = obj[slice(stop)] obj[start:stop] = obj[slice(start, stop)] obj
我有以下表示网页的结构 type Webpage struct { url.URL references []url.URL } 我想将网站表示为网页的集合。我正在使用这个结构,但感觉
我有一个这样的结构: type Headers struct { header string valueFromCalculation string
我正在参观 Golang 网站,我正在尝试消化其中一个示例。目前还不清楚它是如何工作的: package main import "fmt" func main() { s := []int{
我很好奇解包 slice 并将它们作为参数发送给可变参数函数。 假设我们有一个带有可变参数的函数: func unpack(args ...interface{}) 如果我们不想传入它工作的接口(in
我正在尝试解码来自服务器的 gzip 响应,该响应是一个 msgpack 数组或最终被 gzip 压缩的 msgpack 数组。 为了说明这一点,我的回复看起来像这样: gzip(msgpack([m
我是 Go 编程的新手。我在 Go 编程书籍中读到 slice 由三部分组成:指向数组的指针、长度和容量。 我很困惑: nil slice ( slice 没有可指向的底层数组,len = 0,cap
在Go Programming Language书中,作者给出了append()函数的以下代码示例,该函数接受[]int和int作为参数,并将相应地处理调整大小: // gopl.io/ch4/app
我在代码高尔夫游戏中尝试优化字符串复数时遇到了这个怪癖。我的想法是将字符串写成复数形式,然后使用 substr 有条件地切断最后一个字符: var counter = 1; var myText =
我有一个字符串数组:slice1 [][]string。我使用 for 循环获得了我想要的值: for _, i := range slice1 { //[string1 string2] f
我正在尝试实现一个将 TCP 端口 slice 拆分为 x 个其他 slice 的功能。这些 slice 将发送给将扫描这些端口的工作人员,因此 x 由工作人员的数量设置。 这是代码: // crea
我有以下代码 func Sum(a []int) int { res := 0 for _, n := range a { res += n } ret
我是一名优秀的程序员,十分优秀!