Ho scritto una funzione di ricerca binaria come parte di un programma più grande, ma sembra essere più lenta di quanto dovrebbe essere e la profilazione mostra molte chiamate ai metodi in clojure.lang.Numbers .Ricerca binaria in clojure (implementazione/prestazioni)
La mia comprensione è che Clojure può usare le primitive quando può determinare che può farlo. Le chiamate ai metodi in clojure.lang.Numbers sembrano indicare che non sta usando le primitive qui.
Se le variabili di ciclo vengono forzate in ints, si lamenta correttamente che gli argomenti ricorrenti non sono primitivi. Se ho forzato anche quelli, il codice funziona di nuovo, ma di nuovo è lento. La mia unica ipotesi è che (quot (+ low-idx high-idx) 2)
non stia producendo un primitivo ma non sono sicuro di dove andare da qui.
Questo è il mio primo programma in Clojure quindi sentitevi liberi di farmi sapere se ci sono più modi puliti/funzionali/Clojure per fare qualcosa.
(defn binary-search
[coll coll-size target]
(let [cnt (dec coll-size)]
(loop [low-idx 0 high-idx cnt]
(if (> low-idx high-idx)
nil
(let [mid-idx (quot (+ low-idx high-idx) 2) mid-val (coll mid-idx)]
(cond
(= mid-val target) mid-idx
(< mid-val target) (recur (inc mid-idx) high-idx)
(> mid-val target) (recur low-idx (dec mid-idx))
))))))
(defn binary-search-perf-test
[test-size]
(do
(let [test-set (vec (range 1 (inc test-size))) test-set-size (count test-set)]
(time (count (map #(binary-search2 test-set test-set-size %) test-set)))
)))
Grazie. Ero un po 'cauto nel prendere le dimensioni della collezione perché non ho ancora familiarità con tutti i tipi di Clojure. Ho trovato una buona informazione un po 'prima su [link] (http://clojure.org/data_structures). Sto cercando di evitare di chiamare in Java per ora mentre sto imparando Clojure e sto cercando di sfidare me stesso a non chiamare in Java (a meno che non arrivi a un punto in cui non penso che sarei in grado di ottenere la soluzione Clojure dove lo voglio). Cambiare quot a bit shifting sembra aiutare in 1.3 (e non in 1.2). Andando a giocare con gli altri suggerimenti e vedere come va. – Vadim
L'utilizzo di (nth coll n) anziché di (col n) sembra essere leggermente più veloce. – Vadim
L'operatore '=' sembra eseguire sempre la boxe mentre '==' non è – Vadim