哪个更快?使用条件fn或get-in进行映射还是缩小?

时间:2016-11-06 18:25:42

标签: clojure monger

我正在使用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匹配更快?

我非常感谢您提供的帮助。

1 个答案:

答案 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数据类型作为键。