Created
April 27, 2023 23:37
-
-
Save shaunlebron/99a3e8754f2cfaa2a83f027799c30e5e 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
(defmacro =>> | |
"Makes ->> faster if the first form is a collection, and the last form is `sequence`, `into`, or `reduce`" | |
;; adapted from: https://github.com/divs1210/streamer/blob/master/src/streamer/core.clj | |
[coll & xforms-and-term] | |
(let [[xforms term] ((juxt butlast last) xforms-and-term)] | |
(cond | |
;; sequence | |
(or (= term 'sequence) | |
(and (list? term) | |
(= (first term) 'sequence))) | |
(do | |
(assert (= 0 (count (rest term))) "`=>> sequence` must have no args") | |
`(sequence (comp ~@xforms) ~coll)) | |
;; into | |
(and (list? term) | |
(= (first term) 'into)) | |
(let [[_ to] term] | |
(assert (= 1 (count (rest term))) "`=>> into` must have one arg") | |
`(into ~to (comp ~@xforms) ~coll)) | |
;; reduce | |
(and (list? term) | |
(= (first term) 'reduce)) | |
(let [[_ f init] term] | |
(assert (#{1 2} (count (rest term))) "`=>> reduce` must have one or two args") | |
(if init | |
`(transduce (comp ~@xforms) ~f ~init ~coll) | |
`(transduce (comp ~@xforms) ~f ~coll))) | |
:else | |
(throw (ex-info (format "=>> must end with `(sequence)`, `(into ...)`, or `(reduce ...)`. got `%s` instead" term) | |
{:term term}))))) | |
(comment | |
(require '[criterium.core :refer [quick-bench]]) | |
(quick-bench | |
(->> (range 10) | |
(filter even?) | |
(map #(Math/sqrt %)) | |
(reduce *))) ;; => 341 ns | |
(quick-bench | |
(=>> (range 10) | |
(filter even?) | |
(map #(Math/sqrt %)) | |
(reduce *)))) ;; => 206 ns |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment