Skip to content

Instantly share code, notes, and snippets.

@aamedina
Last active January 2, 2016 03:39
Show Gist options
  • Select an option

  • Save aamedina/8245740 to your computer and use it in GitHub Desktop.

Select an option

Save aamedina/8245740 to your computer and use it in GitHub Desktop.
(deftype ConcatVec [meta cnt cnt-a cnt-b a b ^:mutable __hash]
ISequential
Object
(toString [coll]
(pr-str* coll))
IWithMeta
(-with-meta [coll meta] (ConcatVec. meta cnt cnt-a cnt-b a b __hash))
IMeta
(-meta [_] meta)
ICloneable
(-clone [_] (ConcatVec. meta cnt cnt-a cnt-b a b __hash))
ISeqable
(-seq [_] (-seq (into a b)))
ISeq
(-first [_] (or (first a) (first b)))
(-rest [_] (rest (into a b)))
ICounted
(-count [_] cnt)
ICollection
(-conj [coll o] (ConcatVec. meta (inc cnt) cnt-a (inc cnt-b) a (conj b o) __hash))
IStack
(-peek [_] (peek b))
(-pop [_] (ConcatVec. meta (dec cnt) cnt-a (dec cnt-b) a (pop b) __hash))
IPrintWithWriter
(-pr-writer [coll writer opts]
(pr-writer (into a b) writer opts))
IIndexed
(-nth [coll n]
(cond
(< n cnt-a) (-nth a n)
(< n cnt) (-nth b (- n cnt-a))
:else nil))
(-nth [coll n not-found]
(cond
(< n cnt-a) (-nth a n not-found)
(< n cnt) (-nth b (- n cnt-a) not-found)
:else not-found))
ILookup
(-lookup [coll k] (-nth coll k nil))
(-lookup [coll k not-found] (-nth coll k not-found))
IMapEntry
(-key [coll] (-nth coll 0))
(-val [coll] (-nth coll 1))
IAssociative
(-assoc [coll k v]
(cond
(and (<= 0 k) (< k cnt-b))
(ConcatVec. meta cnt cnt-a cnt-b (-assoc a k v) b __hash)
(and (<= cnt-a k) (< k cnt))
(ConcatVec. meta cnt cnt-a cnt-b a (-assoc b k v) __hash)
(== k cnt) (-conj coll v)
:else
(throw (js/Error. (str "Index " k "out of bounds [0," cnt "]")))))
IVector
(-assoc-n [coll n val] (-assoc coll n val))
IReduce
(-reduce [v f]
(ci-reduce v f))
(-reduce [v f start]
(ci-reduce v f start))
IKVReduce
(-kv-reduce [v f init]
(let [step-init (array 0 init)]
(loop [i 0]
(cond
(< i cnt-a)
(let [arr (array-for a i)
len (alength arr)]
(let [init (loop [j 0 init (aget step-init 1)]
(if (< j len)
(let [init (f init (+ j i) (aget arr j))]
(if (reduced? init)
init
(recur (inc j) init)))
(do (aset step-init 0 len)
(aset step-init 1 init)
init)))]
(if (reduced? init)
@init
(recur (+ i (aget step-init 0))))))
(< i cnt)
(let [i (- i cnt-a)
arr (array-for b i)
len (alength arr)]
(let [init (loop [j 0 init (aget step-init 1)]
(if (< j len)
(let [init (f init (+ j i) (aget arr j))]
(if (reduced? init)
init
(recur (inc j) init)))
(do (aset step-init 0 len)
(aset step-init 1 init)
init)))]
(if (reduced? init)
@init
(recur (+ (+ i cnt-a) (aget step-init 0))))))
:else (aget step-init 1)))))
IFn
(-invoke [coll k]
(-nth coll k))
(-invoke [coll k not-found]
(-nth coll k not-found))
IReversible
(-rseq [coll]
(if (pos? cnt)
(RSeq. coll (dec cnt) nil)))
IEmptyableCollection
(-empty [coll] (with-meta cljs.core.PersistentVector.EMPTY meta))
IEquiv
(-equiv [coll other] (equiv-sequential coll other))
IHash
(-hash [coll] (caching-hash coll hash-coll __hash)))
(defn catvec
[a b]
(let [cnt-a (count a)
cnt-b (count b)]
(ConcatVec. (merge (meta a) (meta b)) (+ cnt-a cnt-b) cnt-a cnt-b a b 0)))
;; standard vector concatenation using into benchmark, 1 run
;; I dare not run this 10000 times
(simple-benchmark
[v1 (vec (range 50000))
v2 (vec (range 50000 100000))
v3 (vec (range 100000))]
(-> (into v1 v2)
(subvec 50000 50050)
(into v3)
(subvec 5001 6001))
1)
... 1 runs, 138 msecs
;; simple catvec benchmark, 1 & 10000 runs
(simple-benchmark
[v1 (vec (range 50000))
v2 (vec (range 50000 100000))
v3 (vec (range 100000))]
(-> (catvec v1 v2)
(subvec 50000 50050)
(catvec v3)
(subvec 5001 6001))
1)
... 1 runs, 0 msecs
... 10000 runs, 74 msecs
;; rrb-vector catvec benchmark, 10000 runs
(simple-benchmark
[v1 (vec (range 50000))
v2 (vec (range 50000 100000))
v3 (vec (range 100000))]
(-> (rrb/catvec v1 v2)
(subvec 50000 50050)
(rrb/catvec v3)
(subvec 5001 6001))
1)
... 1 runs, 0 msecs
... 10000 runs, 1039 msecs
both should return
[4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966
4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981
4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997
4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013
5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028
5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044
5045 5046 5047 5048 5049 5050 ...]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment