用于寻路的mgo优化

我在 Go 中实现了一个 A* 算法来找到地图上两个坐标之间的路径。地图数据是使用 mgo 从 MongoDB 集合中获取的。


然而,它非常缓慢。对于 1000 米的路线,它大约需要 4 秒。我对算法的不同部分进行了计时,并得出结论,瓶颈在于从数据库中获取。或者更准确地说:从二进制数据到 Go 能够理解的数据结构的转换。


我尽量少做请求,多线程处理请求以使其更快,这在一定程度上有所帮助。但它并没有我希望的那么快。


似乎我在做一些根本错误的事情。任何建议都会有所帮助。


mongoDB 中的数据结构:(从 OSM 获取的节点)


{ "_id" : NumberLong(194637483),

  "lat" : 55.7079899, 

  "lon" : 13.3756414,

  "neighbours" : [ NumberLong(1566264689), NumberLong(1566264806) ] 

}

Go中的数据结构


type Node struct {

    ID         int64   `bson:"_id" json:"id"`

    Lat        float64 `bson:"lat" json:"lat"`

    Lon        float64 `bson:"lon" json:"lon"`

    Neighbours []int64 `bson:"neighbours" json:"neighbours"`

}

获取一条数据的代码:


func addToBufferLong(buffer *WriteLockMap, session *mgo.Session, at, goal geo.Node, lowerLat, higherLat, lowerLon, higherLon float64) {

    c := session.DB("collectionName").C("nodes")

    query := c.Find(bson.M{"lat": bson.M{"$gt": lowerLat, "$lt": higherLat}, "lon": bson.M{"$gt": lowerLon, "$lt": higherLon}})


    var nodes []geo.Node

    query.All(&nodes)

    for _, node := range nodes {

        tmp := PathNode{0, node.DistanceTo(goal), 0, node}

        buffer.Lock()

        buffer.m[node.ID] = tmp

        buffer.Unlock()

    }

}


达令说
浏览 185回答 1
1回答

繁花如伊

根据现有的信息,我可以推断出:您的机器似乎很慢,也许是嵌入式设备?您调用的阶段db-fetch实际上并未访问数据库。唯一c.Find(...)能做的就是建立一个*mgo.Query价值。该方法有 6 行。这不应超过一毫秒。除非在数据库对象的内部会话状态上存在争用,否则情况似乎并非如此,因为您只使用了 4 个 goroutine。瓶颈似乎是网络和/或反射query.All(&nodes)是在您的数据库上实际执行查询的地方。此外,这个阶段会分配它需要的节点切片,然后通过反射将 bson 迭代解码到您的结构定义中。你可以尝试的一件事: *mgo.iter而不是query.All(...)您可以使用query.Iter()获取 a*mgo.Iter并在您的数据集上批量迭代。这可能会通过更好地随时间分配网络负载来提高性能。使用地理空间索引,Mongo 支持请参阅文档。也许你已经在这样做了。如果没有,它可能会缩短查找时间。将您的象限递归地拆分为子象限。我认为这是显而易见的。分而治之吧?:)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go