Skip to content

Instantly share code, notes, and snippets.

@mhuebert
Last active December 1, 2016 18:16
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 mhuebert/4e826ab01e6684ef1413b15ef9edc547 to your computer and use it in GitHub Desktop.
Save mhuebert/4e826ab01e6684ef1413b15ef9edc547 to your computer and use it in GitHub Desktop.

We want to reduce analysis cache size by deduping info stored in a def and also under its :meta key. Naive deduping can reduce cache size by 20-30%. Per @swannodette, https://clojurians.slack.com/archives/clojurescript/p1480348180020797, this would be a desireable cljs patch.

Open Questions

  • Under what conditions should the :file key contain an absolute path, relative path, file extension, nothing at all?
  • Why does :column differ between :file and :meta?
  • How much of this data can we drop? when and how do cljs applications rely on this metadata?
  • Why does teh :argslist differ between the def and its :meta key?

Output

Below, we read into a compiler state to see how the values in a def differ from those of its :meta key. We get-in'ing paths like:
[:cljs.analyzer/namespaces ~ns :defs ~sym] and [:cljs.analyzer/namespaces ~ns :defs ~sym :meta].

;; cljs.core/rand-int - core name, file is relative path

 :file       cljs/core.cljs
 :meta/:file cljs/core.cljs

 :column       1
 :meta/:column 7
 

;; cljs.core$macros/-> - core macro, file shows output-dir, meta/file is abs. path

 :file       out/cljs/core.cljc
 :meta/:file /Users/MattPro/Dropbox/Sites/planck/planck-cljs/out/cljs/core.cljc

 :column       4
 :meta/:column 19

 :arglists       ([&form &env x & forms])
 :meta/:arglists (quote ([x & forms]))
 

;; cljs.spec/conform - name, file shows output-dir, meta/file is abs. path

 :file       out/cljs/spec.cljs
 :meta/:file /Users/MattPro/Dropbox/Sites/planck/planck-cljs/out/cljs/spec.cljs

 :column       1
 :meta/:column 7
 

;; cljs.spec$macros/def - macro, meta/file has no extension

 :file       cljs/spec.cljc
 :meta/:file cljs.spec

 :column       1
 :meta/:column 11
 

;; maria.user/circle - file and meta/file are absolute paths

 :file       /Users/MattPro/Dropbox/Sites/maria/src/maria/user.cljs
 :meta/:file /Users/MattPro/Dropbox/Sites/maria/src/maria/user.cljs

 :column       1
 :meta/:column 7
 

;; maria.user$macros/user-macro - file is abs. path, meta/file has no extension

 :file       /Users/MattPro/Dropbox/Sites/maria/src/maria/user.clj
 :meta/:file maria.user

 :column       1
 :meta/:column 11

 :arglists       ([&form &env & body])
 :meta/:arglists (quote ([& body]))

This analysis cache was produced using cljs-live, which sources from a ClojureScript output-dir, falling back to Planck repl caches.

;; the following code was run in a bootstrapped clojurescript repl
;; here: maria-d04a7.firebaseapp.com
(require '[cljs.spec :as s :include-macros true])
(require 'maria.eval)
(def cs maria.eval/c-state)
(require '[cljs.analyzer :as ana])
(defn get-def [ns sym]
(-> @cs
(get-in [:cljs.analyzer/namespaces ns :defs sym])
(dissoc :meta)))
(defn get-meta [ns sym]
(-> @cs
(get-in [:cljs.analyzer/namespaces ns :defs sym :meta])))
(defn show-str [s] (html [:div s]))
(defn compare-var-meta [n]
(let [ns (symbol (namespace n))
sym (symbol (name n))
meta# (get-meta ns sym)
def# (get-def ns sym)]
(show-str
(str "\n"(symbol ns sym) "\n"
(apply str
(for [k (keys meta#)
:when (or (= k :file)
(not= (get meta# k)
(get def# k)))]
(str "\n " k" " (get def# k) "\n"
" :meta/" k" " (get meta# k) "\n") ))))))
(map compare-var-meta ['cljs.spec/conform
'cljs.spec$macros/def
'cljs.core/rand-int
'maria.user/circle
'maria.user$macros/user-macro])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment