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