我在 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 關注
- 227 瀏覽
添加回答
舉報
0/150
提交
取消