2016-11-06 68 views
0

我正在使用monger并使用find-maps从我的mongo nosql数据库中获取批处理。它返回一个我打算在我的函数调用链中下游用作数据存储参数(参考)的数组。在未来的函数调用中,我将访问相应的ID。我希望使用此ID作为查找来在我的数据存储区中进行读取,因此我不必再拨打另一个monger电话。数组形式的数据存储似乎不是通过ID访问对象的最快方式......但我不确定。哪个更快?映射或减少条件FN或进入?

如果我需要从此数据存储阵列中获得一个对象,然后我需要如果后使用这样的函数(即具有登录(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 
    ) 
) 

相反,我最初贩子电话,我创建了一个键/ 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-中,这将是更快,因为我会用钥匙来取?

我很困惑,因为:当我使用get-中,是不是要遍历在关键的每个键/ VAL有对象,直到找到键和fetch_id之间的匹配:

(let [report (createReportFromObjArray inputarray) 
     target_val (get-in report [(keyword fetch_id)])] 

为什么不能在每个密钥上记录(n)?也许它更快,因为它可以停止,当它发现第一个“匹配”的地图/减少必须通过log(n)的整个方式?如何快速迭代数组中的每个元素并检查id是否与fetch_id匹配?

我非常感谢您的帮助。

回答

3

在你的第二个代码示例中,你正在线性时间构建一个Clojure哈希映射。通过get及派生它们具有O(log32(N))的查找性能。

在第一个示例中,您扫描整个输入并返回与ID或空散列映射相匹配的最后一个元素,可能是无意中的。

_

我建议使用(group-by :_id)代替第二代码的例子。我也推荐使用(first (filter (comp #{fetch_id} :_id) inputarray))来代替第一个例子。

避免通过keyword投射到关键字 - Clojure关键字通常应该在编译时知道。地图支持Arbirtrary数据类型作为键。

+0

所以当我使用(get-in ...)时,有一个内置的算法比不得不通过每个键以找到关联值的性能更好(O(log32(N))? –

+1

在第二个和第三个示例中,您将演示如何构建哈希映射,并通过密钥通过get-in(也可以使用get)查找。这就是表现。由于在第二个示例中构建哈希映射,因此在哈希映射中查找关键字的性能明显优于第一个示例,在该示例中迭代所有元素,直到找到某些内容为止。您可能想了解https://en.wikipedia.org/wiki/Hash_table - 或者我误解了您的问题。 –