2015-10-19 21 views
2

我的算法如下 -Clojure的減速/圖不工作

(defn max-of 
[args] 
(into [] (apply map #(apply max %&) args))) 

工作正常。

(max-of [[1 7] [3 5] [7 9] [2 2]])返回[7 9]

它基本上發現上的各位置的最大元素。 7是最大的第一個元素是集合,9是最大的第二個元素。然而,試圖用reducer/mapcore.reducers的時候,我得到

CompilerException clojure.lang.ArityException: Wrong number of args (21) passed to: reducers/map

所以這不起作用 -

(defn max-of 
[args] 
(into [] (apply r/map #(apply max %&) args))) 

爲什麼?

UPDATE

我最後的代碼是

(defn max-of [[tuple & tuples]] 
    (into [] (r/fold (fn 
      ([] tuple) 
      ([t1 t2] (map max t1 t2))) 
      (vec tuples)))) 

運行快速板凳上它給Execution time mean : 626.125215 ms

我這有其他的算法,我寫之前 -

(defn max-fold 
    [seq-arg] 
    (loop [acc (transient []) t seq-arg] 
     (if (empty? (first t)) 
      (rseq (persistent! acc)) 
      (recur (conj! acc (apply max (map peek t))) (map pop t))))) 

它做同樣的事情。對於這個我得到了 - Execution time mean : 308.200310 ms這比r/fold平行的東西快兩倍。任何想法爲什麼?

順便說一句,如果我從r/fold東西刪除into []東西,那麼我得到Execution time mean : 13.101313 ms

+0

猜測它給你這個結果沒有'into',因爲'fold'是懶惰的,所以減少不會發生,直到第一次使用結果 – leetwinski

+0

也我認爲摺疊方法由於並行處理基礎架構開銷,這可能會因所提供的任務的複雜性而抵消。在你的情況下,任務是微不足道的。此外,「瞬態」方法是一個很好的優化,可能它是最正確的。 – leetwinski

+0

感謝所有的見解 – Lordking

回答

2

這個問題的答案,爲什麼已經被賦予了問題。所以讓我們回答下一個問題:「你想做什麼?「

據我是如何理解你的目標(找到在元組位置的最大元素)和並行可能做到這一點(因爲你要使用減速),這是你必須做的

什麼
(defn max-of [tuples] 
    (r/fold (fn 
      ([] (first tuples)) 
      ([t1 t2] (map max t1 t2))) 
      ((rest tuples))) 

user> (max-of [[1 7] [3 5] [7 9] [2 2]]) 
(7 9) 

(max-of [[1 2 3] [3 2 1] [4 0 4]]) 
(4 2 4) 

user> (max-of []) 
nil 

user> (max-of [[1 2 3]]) 
[1 2 3] 

或解構甚至更好:

(defn max-of [[tuple & tuples]] 
    (r/fold (fn 
      ([] tuple) 
      ([t1 t2] (map max t1 t2))) 
      tuples)) 

更新: 大數據,你應該優化它,並切換到使用向量

(defn max-of [[tuple & tuples]] 
    (r/fold (fn 
      ([] tuple) 
      ([t1 t2] (map max t1 t2))) 
      (vec tuples))) 

user> (max-of (repeat 1000000 [1 2 3 4 5 6 7 8 9 10])) 
(1 2 3 4 5 6 7 8 9 10) 
+0

謝謝,這是有效的。但是,當我的數據集非常大時,出現堆棧溢出錯誤。它是否加載了內存中的所有內容? – Lordking

+0

有多大?它有多少個元組?每個元組有多長? – leetwinski

+0

它有420420項。每個項目有10個元素。 – Lordking

3

r/map需要[f][f coll] - 讓你的apply的做法不會在這裏工作

user=> (doc r/map) 
------------------------- 
clojure.core.reducers/map 
([f] [f coll]) 

user=> (doc map) 
------------------------- 
clojure.core/map 
([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]) 
+0

啊..謝謝。任何想法如何使用r/map來解決我的問題?我想我會需要r/reducer。 – Lordking

+0

只是要清楚 - 你想找到具有最大'int'的元組,而不管第一或第二位置? – birdspider

+0

沒有。我想找到每個位置的最大元素。所以對於[[3 4] [5 2]]'我會得到'[5 4]'。由於3,5是第一個元素,5是較大的元素。類似地,對於最後一個位置,它比較4,2。4返回,因爲它更大 – Lordking