Escribí una función de búsqueda binaria como parte de un programa más grande, pero parece ser más lenta de lo que debería y el perfil muestra muchas llamadas a métodos en clojure.lang.Numbers .Búsqueda binaria en clojure (implementación/rendimiento)
Según entiendo, Clojure puede usar primitivas cuando puede determinar que puede hacerlo. Las llamadas a los métodos en clojure.lang.Numbers parecen indicar que no está utilizando primitivas aquí.
Si fuerzo las variables de bucle a las entradas, se queja correctamente de que los argumentos recurrentes no son primitivos. Si los coacciono también, el código funciona nuevamente, pero de nuevo es lento. Mi única conjetura es que (quot (+ low-idx high-idx) 2)
no está produciendo un primitivo, pero no estoy seguro de dónde ir desde aquí.
Este es mi primer programa en Clojure, así que siéntase libre de decirme si hay formas más limpias/funcionales/Clojure de hacer algo.
(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)))
)))
Gracias. Estaba siendo un poco cauteloso acerca de tomar el tamaño de la colección, ya que aún no estoy muy familiarizado con todos los tipos de Clojure. Encontré buena información un poco antes en [link] (http://clojure.org/data_structures). Estoy intentando evitar llamar a Java por ahora mientras estoy aprendiendo Clojure y tratando de desafiarme a mí mismo para no llamar a Java (a menos que llegue a un punto en el que no creo que pueda obtener la solución Clojure a donde yo quiero). Cambiar quot al cambio de bit pareció ayudar en 1.3 (y no en 1.2). Voy a jugar con sus otras sugerencias y ver cómo va. – Vadim
El uso de (n. ° coll n) en lugar de (col n) parece ser un poco más rápido. – Vadim
'=' el operador parece realizar siempre el boxeo, mientras que '==' no lo hace – Vadim