[#419] classpath optimizations / first step towards data_readers

This commit is contained in:
Michiel Borkent 2020-05-14 22:31:49 +02:00 committed by GitHub
parent eef0b046cd
commit de5168adab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 30 deletions

View file

@ -7,33 +7,39 @@
(set! *warn-on-reflection* true)
(defprotocol IResourceResolver
(getResource [this path opts]))
(getResource [this paths opts])
(getResources [this paths opts]))
(deftype DirectoryResolver [path]
IResourceResolver
(getResource [this resource-path {:keys [:url?]}]
(let [f (io/file path resource-path)]
(when (.exists f)
(if url?
(java.net.URL. (str "file:"
(.getCanonicalPath f)))
{:file (.getCanonicalPath f)
:source (slurp f)})))))
(getResource [this resource-paths {:keys [:url?]}]
(some
(fn [resource-path]
(let [f (io/file path resource-path)]
(when (.exists f)
(if url?
(java.net.URL. (str "file:"
(.getCanonicalPath f)))
{:file (.getCanonicalPath f)
:source (slurp f)}))))
resource-paths)))
(defn path-from-jar
[^java.io.File jar-file path {:keys [:url?]}]
[^java.io.File jar-file resource-paths {:keys [:url?]}]
(with-open [jar (JarFile. jar-file)]
(when-let [entry (.getEntry jar path)]
(if url?
(java.net.URL.
(str "jar:file:" (.getCanonicalPath jar-file) "!/" path))
{:file path
:source (slurp (.getInputStream jar entry))}))))
(some (fn [path]
(when-let [entry (.getEntry jar path)]
(if url?
(java.net.URL.
(str "jar:file:" (.getCanonicalPath jar-file) "!/" path))
{:file path
:source (slurp (.getInputStream jar entry))})))
resource-paths)))
(deftype JarFileResolver [path]
(deftype JarFileResolver [jar-file]
IResourceResolver
(getResource [this resource-path opts]
(path-from-jar path resource-path opts)))
(getResource [this resource-paths opts]
(path-from-jar jar-file resource-paths opts)))
(defn part->entry [part]
(if (str/ends-with? part ".jar")
@ -42,8 +48,10 @@
(deftype Loader [entries]
IResourceResolver
(getResource [this resource-path opts]
(some #(getResource % resource-path opts) entries)))
(getResource [this resource-paths opts]
(some #(getResource % resource-paths opts) entries))
(getResources [this resource-paths opts]
(keep #(getResource % resource-paths opts) entries)))
(defn loader [^String classpath]
(let [parts (.split classpath (System/getProperty "path.separator"))
@ -53,11 +61,9 @@
(defn source-for-namespace [loader namespace opts]
(let [ns-str (name namespace)
^String ns-str (munge ns-str)
path (.replace ns-str "." (System/getProperty "file.separator"))
;; TODO: check .bb .clj etc while opening the jar file, this might be
;; faster.
paths (map #(str path %) [".bb" ".clj" ".cljc"])]
(some #(getResource loader % opts) paths)))
base-path (.replace ns-str "." (System/getProperty "file.separator"))
resource-paths (mapv #(str base-path %) [".bb" ".clj" ".cljc"])]
(getResource loader resource-paths opts)))
;;;; Scratch
@ -65,7 +71,5 @@
(def cp "src:feature-xml:feature-core-async:feature-yaml:feature-csv:feature-transit:feature-java-time:feature-java-nio:sci/src:babashka.curl/src:babashka.pods/src:resources:sci/resources:/Users/borkdude/.m2/repository/com/cognitect/transit-java/1.0.343/transit-java-1.0.343.jar:/Users/borkdude/.m2/repository/org/clojure/clojure/1.10.2-alpha1/clojure-1.10.2-alpha1.jar:/Users/borkdude/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar:/Users/borkdude/.m2/repository/org/clojure/tools.analyzer/1.0.0/tools.analyzer-1.0.0.jar:/Users/borkdude/.m2/repository/org/clojure/tools.logging/0.6.0/tools.logging-0.6.0.jar:/Users/borkdude/.m2/repository/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar:/Users/borkdude/.m2/repository/org/clojure/spec.alpha/0.2.187/spec.alpha-0.2.187.jar:/Users/borkdude/.m2/repository/org/clojure/tools.cli/1.0.194/tools.cli-1.0.194.jar:/Users/borkdude/.m2/repository/org/clojure/tools.analyzer.jvm/1.0.0/tools.analyzer.jvm-1.0.0.jar:/Users/borkdude/.m2/repository/borkdude/graal.locking/0.0.2/graal.locking-0.0.2.jar:/Users/borkdude/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.10.2/jackson-dataformat-cbor-2.10.2.jar:/Users/borkdude/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar:/Users/borkdude/.m2/repository/org/flatland/ordered/1.5.9/ordered-1.5.9.jar:/Users/borkdude/.m2/repository/org/postgresql/postgresql/42.2.12/postgresql-42.2.12.jar:/Users/borkdude/.m2/repository/fipp/fipp/0.6.22/fipp-0.6.22.jar:/Users/borkdude/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.10.2/jackson-core-2.10.2.jar:/Users/borkdude/.m2/repository/org/yaml/snakeyaml/1.25/snakeyaml-1.25.jar:/Users/borkdude/.m2/repository/org/ow2/asm/asm/5.2/asm-5.2.jar:/Users/borkdude/.gitlibs/libs/clj-commons/conch/9aa7724e925cb8bf163e0b62486dd420b84e5f0b/src:/Users/borkdude/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar:/Users/borkdude/.m2/repository/seancorfield/next.jdbc/1.0.424/next.jdbc-1.0.424.jar:/Users/borkdude/.m2/repository/org/clojure/data.xml/0.2.0-alpha6/data.xml-0.2.0-alpha6.jar:/Users/borkdude/.m2/repository/org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar:/Users/borkdude/.m2/repository/borkdude/edamame/0.0.11-alpha.9/edamame-0.0.11-alpha.9.jar:/Users/borkdude/.m2/repository/org/clojure/data.csv/1.0.0/data.csv-1.0.0.jar:/Users/borkdude/.m2/repository/com/cognitect/transit-clj/1.0.324/transit-clj-1.0.324.jar:/Users/borkdude/.m2/repository/clj-commons/clj-yaml/0.7.1/clj-yaml-0.7.1.jar:/Users/borkdude/.m2/repository/org/clojure/core.rrb-vector/0.1.1/core.rrb-vector-0.1.1.jar:/Users/borkdude/.m2/repository/persistent-sorted-set/persistent-sorted-set/0.1.2/persistent-sorted-set-0.1.2.jar:/Users/borkdude/.m2/repository/cheshire/cheshire/5.10.0/cheshire-5.10.0.jar:/Users/borkdude/.m2/repository/tigris/tigris/0.1.2/tigris-0.1.2.jar:/Users/borkdude/.m2/repository/org/clojure/tools.reader/1.3.2/tools.reader-1.3.2.jar:/Users/borkdude/.m2/repository/datascript/datascript/0.18.11/datascript-0.18.11.jar:/Users/borkdude/.m2/repository/org/hsqldb/hsqldb/2.4.0/hsqldb-2.4.0.jar:/Users/borkdude/.m2/repository/org/clojure/core.memoize/0.8.2/core.memoize-0.8.2.jar:/Users/borkdude/.m2/repository/org/clojure/data.priority-map/0.0.7/data.priority-map-0.0.7.jar:/Users/borkdude/.m2/repository/org/clojure/java.data/1.0.64/java.data-1.0.64.jar:/Users/borkdude/.m2/repository/borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1.jar:/Users/borkdude/.m2/repository/nrepl/bencode/1.1.0/bencode-1.1.0.jar:/Users/borkdude/.m2/repository/org/clojure/core.cache/0.8.2/core.cache-0.8.2.jar:/Users/borkdude/.m2/repository/org/clojure/core.async/1.1.587/core.async-1.1.587.jar:/Users/borkdude/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.10.2/jackson-dataformat-smile-2.10.2.jar:/Users/borkdude/.m2/repository/org/clojure/data.codec/0.1.0/data.codec-0.1.0.jar:/Users/borkdude/.m2/repository/javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar")
(def l (loader cp))
(source-for-namespace l 'babashka.impl.cheshire nil)
(time (:file (source-for-namespace l 'cheshire.core nil))) ;; 20ms -> 4ms
(def jf (JarFile. (io/file "/Users/borkdude/.m2/repository/cheshire/cheshire/5.10.0/cheshire-5.10.0.jar")))
(.getEntry jf "cheshire/core.clj")
(time (:file (source-for-namespace l 'cheshire.core nil))) ;; 20ms -> 2.25mms
)

View file

@ -456,6 +456,12 @@ If neither -e, -f, or --socket-repl are specified, then the first argument that
(let [res (cp/source-for-namespace loader namespace nil)]
(when uberscript (swap! uberscript-sources conj (:source res)))
res)))
data-readers (delay (time (when-let [{:keys [:loader]} @cp-state]
(prn (cp/getResources
loader
["data_readers.clj"
"data-readers.cljc"] nil)))))
;;_ (prn @data-readers)
_ (when file (vars/bindRoot sci/file (.getCanonicalPath (io/file file))))
;; TODO: pull more of these values to compile time
opts {:aliases aliases
@ -467,7 +473,9 @@ If neither -e, -f, or --socket-repl are specified, then the first argument that
'*warn-on-reflection* reflection-var
'load-file load-file*))
(assoc-in ['clojure.java.io 'resource]
#(when-let [{:keys [:loader]} @cp-state] (cp/getResource loader % {:url? true})))
(fn [path]
(when-let [{:keys [:loader]} @cp-state]
(cp/getResource loader [path] {:url? true}))))
(assoc-in ['user (with-meta '*input*
(when-not stream?
{:sci.impl/deref! true}))] input-var)