Skip to content

Instantly share code, notes, and snippets.

@escherize
Created April 23, 2019 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save escherize/da64c10d1b8c014a0eb46f121f3d1fda to your computer and use it in GitHub Desktop.
Save escherize/da64c10d1b8c014a0eb46f121f3d1fda to your computer and use it in GitHub Desktop.
(ns scratch.memo)
(defn add-one-api-call [n]
(println "Getting Request for: " n)
(Thread/sleep 1000)
{:response (+ 1 n)})
(defn request [& ns]
(let [cached-api-call (memoize add-one-api-call)]
(mapv cached-api-call ns)))
;; notice below, we only request 1 Once:
(comment (time (request 1 2 3 1)))
;; Prints:
;; Getting Request for: 1
;; Getting Request for: 2
;; Getting Request for: 3
;; "Elapsed time: 3005.887448 msecs"
;;=> [{:response 2} {:response 3} {:response 4} {:response 2}]
;; but notice it takes over 3 seconds, and is synchronous, we can do
;; better... pmap can do that:
(defn request-2 [& ns]
(let [cached-api-call (memoize add-one-api-call)]
(vec (pmap cached-api-call ns))))
(time (request-2 1 2 3 1))
;; Prints:
;; Getting Request for: Getting Request for: Getting Request for: 123
;;
;;
;; Getting Request for: 1
;; "Elapsed time: 1002.294841 msecs"
;; If you have a keen eye, you'll notice even though we wrapped our
;; api call with memoization we failed to use it, since the response
;; for 1 didn't come back in time to fill in the cache for
;; cached-api-call.
;; So, let's ignore duplicates like this:
(defn request-3 [& ns]
(let [workers (mapv #(future [% (add-one-api-call %)]) (distinct ns))
n->result (into {} (mapv deref workers))]
(mapv n->result ns)))
;; Notice: 1 only printed once!
(time (request-3 1 2 3 1))
;; Prints:
;; Getting Request for: Getting Request for: 2
;; Getting Request for: 13
;;
;; "Elapsed time: 1001.408266 msecs"
;;=> [{:response 2} {:response 3} {:response 4} {:response 2}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment