Skip to content

Instantly share code, notes, and snippets.

@mfikes
Created June 4, 2017 23:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfikes/39f9dd9bec474faa8e81573b92538845 to your computer and use it in GitHub Desktop.
Save mfikes/39f9dd9bec474faa8e81573b92538845 to your computer and use it in GitHub Desktop.
ClassLoader.getResource

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))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment