Fork me on GitHub
#meander
<
2021-04-30
>
ribelo22:04:36

what is the fastest way to scan a collection? there is something faster than a m/scan?

(require '[taoensso.encore :as enc])
(require '[meander.epsilon :as m])

(def data (vec (repeatedly 1000000 (fn [] {:a (* (rand-int 100) (if (enc/chance 0.5) 1 -1))
                                           :b (* (rand-int 100) (if (enc/chance 0.5) 1 -1))
                                           :c (* (rand-int 100) (if (enc/chance 0.5) 1 -1))}))))

(enc/qb 1

  (doall
   (m/search data
     (m/scan {:a 1 :b 1 :c 1 :as ?m}) ?m))
  
  (->> data
       (filterv
        (fn [m]
          (m/find m
            {:a 1 :b 1 :c 1 :as ?m} ?m)))))
;; => [127.33 60.28] - in ms

noprompt22:04:35

How fast is

(m/find data [(m/or {:a 1 :b 1 :c 1 :as !m} _) ...] !m)

ribelo23:04:18

(enc/qb 1
  (doall
   (m/search data
     (m/scan {:a 1 :b 1 :c 1 :as ?m}) ?m))
  
  (m/find data [(m/or {:a 1 :b 1 :c 1 :as !m} _) ...] !m)
  
  (->> data
       (filterv
        (fn [m]
          (m/find m
            {:a 1 :b 1 :c 1 :as ?m} ?m)))))
;; => [125.22 85.2 55.35]

ribelo23:04:41

is definitely faster

noprompt23:04:53

The first two are going to have some overhead at the moment.

noprompt23:04:37

You could always make a macro that uses filter and find together the way you have them.