If you profile incremental compilation where you repeately touch your source files and have it re-compile, you will see that
java.lang.ClassLoader.getResource()
appears at the top of the profile, and the primary call site is io/resource
calls in
cljs.util/ns->source
.
If you look at the call patterns, lots of calls are made with ns of goog.*
, and this always returns nil
. On the other hand,
there are calls for namespaces that won't change.
Re-writing this to short-circuit goog.*
to return nil
, and to cache "core" namespaces, eliminates ClassLoader.getResource()
from the top of the profile. It also seems to speed up my incremental compile loop by perhaps 5–10%.
(def ^:private ns-source-cache (atom {}))
(defn- ns-starts-with?
[ns prefix]
(string/starts-with? (name ns) prefix))
(defn ns->source
"Given a namespace as a symbol return the corresponding resource if it exists."
[ns]
(if (ns-starts-with? ns "goog.")
nil
(if-let [source (get @ns-source-cache ns)]
source
(let [source (or (io/resource (ns->relpath ns :cljs))
(io/resource (ns->relpath ns :cljc)))]
(when (and source
(or (ns-starts-with? ns "cljs.")
(ns-starts-with? ns "clojure.")))
(swap! ns-source-cache assoc ns source))
source))))