| 
10 | 10 | 
 
  | 
11 | 11 | (set! *warn-on-reflection* true)  | 
12 | 12 | 
 
  | 
 | 13 | +(defprotocol CollReduce  | 
 | 14 | +  "Protocol for collection types that can implement reduce faster than  | 
 | 15 | +  first/next recursion. Called by clojure.core/reduce. Baseline  | 
 | 16 | +  implementation defined in terms of Iterable."  | 
 | 17 | +  (coll-reduce [coll f] [coll f val]))  | 
 | 18 | + | 
13 | 19 | (defprotocol InternalReduce  | 
14 | 20 |   "Protocol for concrete seq types that can reduce themselves  | 
15 | 21 |    faster than first/next recursion. Called by clojure.core/reduce."  | 
16 | 22 |   (internal-reduce [seq f start]))  | 
17 | 23 | 
 
  | 
 | 24 | +(defn- seq-reduce  | 
 | 25 | +  ([coll f]  | 
 | 26 | +     (if-let [s (seq coll)]  | 
 | 27 | +       (internal-reduce (next s) f (first s))  | 
 | 28 | +       (f)))  | 
 | 29 | +  ([coll f val]  | 
 | 30 | +     (let [s (seq coll)]  | 
 | 31 | +       (internal-reduce s f val))))  | 
 | 32 | + | 
 | 33 | +(extend-protocol CollReduce  | 
 | 34 | +  nil  | 
 | 35 | +  (coll-reduce  | 
 | 36 | +   ([coll f] (f))  | 
 | 37 | +   ([coll f val] val))  | 
 | 38 | + | 
 | 39 | +  Object  | 
 | 40 | +  (coll-reduce  | 
 | 41 | +   ([coll f] (seq-reduce coll f))  | 
 | 42 | +   ([coll f val] (seq-reduce coll f val)))  | 
 | 43 | + | 
 | 44 | +  ;;aseqs are iterable, masking internal-reducers  | 
 | 45 | +  clojure.lang.ASeq  | 
 | 46 | +  (coll-reduce  | 
 | 47 | +   ([coll f] (seq-reduce coll f))  | 
 | 48 | +   ([coll f val] (seq-reduce coll f val)))  | 
 | 49 | + | 
 | 50 | +  ;;for range  | 
 | 51 | +  clojure.lang.LazySeq  | 
 | 52 | +  (coll-reduce  | 
 | 53 | +   ([coll f] (seq-reduce coll f))  | 
 | 54 | +   ([coll f val] (seq-reduce coll f val)))  | 
 | 55 | + | 
 | 56 | +  ;;vector's chunked seq is faster than its iter  | 
 | 57 | +  clojure.lang.PersistentVector  | 
 | 58 | +  (coll-reduce  | 
 | 59 | +   ([coll f] (seq-reduce coll f))  | 
 | 60 | +   ([coll f val] (seq-reduce coll f val)))  | 
 | 61 | +    | 
 | 62 | +  Iterable  | 
 | 63 | +  (coll-reduce  | 
 | 64 | +   ([coll f]  | 
 | 65 | +      (let [iter (.iterator coll)]  | 
 | 66 | +        (if (.hasNext iter)  | 
 | 67 | +          (loop [ret (.next iter)]  | 
 | 68 | +            (if (.hasNext iter)  | 
 | 69 | +              (recur (f ret (.next iter)))  | 
 | 70 | +              ret))  | 
 | 71 | +          (f))))  | 
 | 72 | +   ([coll f val]  | 
 | 73 | +      (let [iter (.iterator coll)]  | 
 | 74 | +        (loop [ret val]  | 
 | 75 | +          (if (.hasNext iter)  | 
 | 76 | +            (recur (f ret (.next iter)))  | 
 | 77 | +            ret)))))  | 
 | 78 | +  )  | 
 | 79 | + | 
18 | 80 | (extend-protocol InternalReduce  | 
19 | 81 |   nil  | 
20 | 82 |   (internal-reduce  | 
 | 
0 commit comments