Last active
May 19, 2022 18:34
-
-
Save fogus/678bf3f506195d212a8d0fece3c6d8d4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;;; 0 - naive | |
(defn take+rest0 [n coll] | |
[(->> coll (take n) vec) | |
(drop n coll)]) | |
; "Elapsed time: 700 msecs" with (range), take 10 | |
; "Elapsed time: 5860 msecs" with (range), take 100 | |
; "Elapsed time: 818 msecs" with [0...99999], take 10 | |
; "Elapsed time: 6439 msecs" with [0...99999], take 100 | |
;; 2 - explicit transient with return of tail | |
(defn take+rest2 [n coll] | |
(loop [head (transient []) | |
n n | |
tail coll] | |
(if (and (seq tail) (pos? n)) | |
(recur (conj! head (first tail)) (dec n) (rest tail)) | |
[(persistent! head) tail]))) | |
; "Elapsed time: 601 msecs" with coll seq, take 10 | |
; "Elapsed time: 4152 msecs" with coll seq, take 100 | |
; "Elapsed time: 723 msecs" with (range), take 10 | |
; "Elapsed time: 5920 msecs" with (range), take 100 | |
; "Elapsed time: 732 msecs" with [0...99999], take 10 | |
; "Elapsed time: 4254 msecs" with [0...99999], take 100 | |
; "Elapsed time: 1691 msecs" with (take 200 (range)), take 10 | |
; "Elapsed time: 14221 msecs" with (range), take 100 | |
;; 3 - use of into for head, drop for tail | |
(defn take+rest3 | |
[n coll] | |
[(into [] (take n) coll) | |
(drop n coll)]) | |
; "Elapsed time: 565 msecs" with coll seq, take 10 | |
; "Elapsed time: 2762 msecs" with coll seq, take 100 | |
; "Elapsed time: 462 msecs" with (range), take 10 | |
; "Elapsed time: 2755 msecs" with (range), take 100 | |
; "Elapsed time: 517 msecs" with [0...99999], take 10 | |
; "Elapsed time: 2777 msecs" with [0...99999], take 100 | |
; "Elapsed time: 1353 msecs" with (take 200 (range)), take 10 | |
; "Elapsed time: 11327 msecs" with (range), take 100 | |
(defn drop-eager | |
"eager/fast version of drop" | |
[n coll] | |
(if (instance? Iterable coll) | |
(let [i (.iterator ^Iterable coll)] | |
(loop [n n] | |
(if (and (pos? n) (.hasNext i)) | |
(do (.next i) | |
(recur (dec n))) | |
(iterator-seq i)))) ;;here we start losing | |
(nthrest coll n))) | |
;; 4 - use of into for head, drop-eager for tail | |
(defn take+rest4 | |
"Returns a vector with two elements. The first is a collection of the first n | |
items in coll. The second is a collection of the rest of the items in coll, if any." | |
[n coll] | |
[(into [] (take n) coll) | |
(drop-eager n coll)]) | |
;; TBD | |
(def take+rest99 split-at) | |
; "Elapsed time: 1021 msecs" with coll seq, take 10 | |
; "Elapsed time: 7944 msecs" with coll seq, take 100 | |
; "Elapsed time: 1111 msecs" with (range), take 10 | |
; "Elapsed time: 9450 msecs" with (range), take 100 | |
; "Elapsed time: 1144 msecs" with [0...99999], take 10 | |
; "Elapsed time: 9023 msecs" with [0...99999], take 100 | |
; "Elapsed time: 1701 msecs" with (take 200 (range)), take 10 | |
; "Elapsed time: 15743 msecs" with (range), take 100 | |
(comment | |
;; loop with range | |
(let [n 100 | |
f take+rest2] | |
(dotimes [_ 10] | |
(time (dotimes [_ 1000000] | |
(let [[head tail] (f n (range))] | |
(count head)))))) | |
;; loop with vec | |
(let [coll (vec (range 100000)) | |
n 100 | |
f take+rest3] | |
(dotimes [_ 10] | |
(time (dotimes [_ 1000000] | |
(let [[head tail] (f n coll)] | |
(count head)))))) | |
;; loop with lazy seq | |
(let [n 100 | |
f take+rest3] | |
(dotimes [_ 10] | |
(time (dotimes [_ 1000000] | |
(let [[head tail] (f n (take 200 (range)))] | |
(count head)))))) | |
;; loop with coll seq | |
(let [coll (vec (range 100000)) | |
n 100 | |
f take+rest3] | |
(dotimes [_ 10] | |
(time (dotimes [_ 1000000] | |
(let [[head tail] (f n (seq coll))] | |
(count head)))))) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment