我正在使用monger并使用find-maps从我的mongo nosql数据库中获取批处理。它返回一个我打算在我的函数调用链中作为数据存储区参数(引用)下游使用的数组。在那些未来的函数调用中,我将有权访问相应的id。我希望使用这个id作为查询来获取我的数据存储区,这样我就不必再进行一次monger调用了。数组形式的数据存储区似乎不是通过id访问对象的最快方式....但我不确定。
如果我需要从这个数据存储阵列派生一个对象,那么我需要使用这样的函数(必须在每个元素上记录(n))
(defn fetchObjFromArray [fetch_id inputarray]
(reduce (fn [reduced_obj element_obj]
(if (= fetch_id (get-in element_obj [:_id]))
element_obj ;; ignoring duplicates for conversation
reduced_obj
)
)
{}
inputarray
)
)
相反,如果在我的初始monger调用之后,我使用如下函数创建一个key / val哈希对象:
(defn createReportFromObjArray [inputarray]
(reduce (fn [returnobj elementobj]
(let [_id (get-in elementobj [:_id])
keyword (keyword _id)]
(assoc returnobj keyword elementobj)
) ;; ignoring duplicates for conversation
)
{}
inputarray)
)
然后我的后续调用可能会改为使用get-in而且会更快,因为我会按键获取?
我很困惑,因为:当我使用get-in时,它不必遍历key / val中的每个键都有对象,直到它找到键和fetch_id之间的匹配:
(let [report (createReportFromObjArray inputarray)
target_val (get-in report [(keyword fetch_id)])]
为什么不进入每个键都需要记录(n)?也许它更快,因为当它找到第一个"匹配"它可以停止map / reduced必须通过log(n)全程运行?这比迭代遍历数组中的每个元素并检查id是否与fetch_id匹配更快?
我非常感谢您提供的帮助。
答案 0 :(得分:3)
在第二个代码示例中,您将在线性时间内构建Clojure哈希映射。通过set(CMAKE_CXX_CLANG_TIDY "clang-tidy" "-checks=*")
和派生,他们具有O(log32(N))的查找性能。
在第一个示例中,您扫描整个输入并返回与ID或空哈希映射匹配的最后一个元素,可能是无意中。
_
我建议使用get
代替第二个代码示例。我还建议使用(group-by :_id)
代替第一个示例。
避免通过(first (filter (comp #{fetch_id} :_id) inputarray))
转换为关键字 - 通常在编译时可以知道Clojure关键字。地图支持arbirtrary数据类型作为键。