你好!
我阅读了有关如何在开发过程中减少REPL启动时间的文章,并尝试将以下知识应用于使用Leiningen(在文章中,Alex展示了使用deps.edn的此实践)启动REPL。
我的步骤
我重写了clojure.core/load变量,以跟踪加载模块所需的时间。
(alter-var-root #'clojure.core/load (fn [origin-fn]
(if (get (meta origin-fn) ::track-load?)
origin-fn
(vary-meta (fn [& args]
(let [start# (System/nanoTime)
ret# (apply origin-fn args)
elapsed-ms# (/ (double (- (System/nanoTime) start#)) 1000000.0)]
(newline)
(pr {:args (vec args)
:ms elapsed-ms#})
(newline)
ret#))
merge
{::track-load? true}))))
我注意到加载核心Clojure部分需要时间约0.10-0.20毫秒,而加载第三方库模块(例如cheshire)则需要约200-400毫秒。
根据我的理解,减少REPL启动时间的主要思想是,如果clj模块未更改,则编译后的类的优先级高于clj模块。因此,我们可以编译第三方库,并且我们可以受益于不解析其clj文件而使用其编译后的类。
我通过Leiningen uberjar编译了所有Clojure文件(我的和库)并将编译后的类文件所在的文件夹添加到:checkout-deps-shares,我想这是向类路径添加包含类文件的文件夹的方式。
:checkout-deps-shares [:source-paths :test-paths
~(fn [p] (str (:root p) "/target/uberjar/classes/*"))]
然后我重新启动了REPL,重写了clojure.core/load来跟踪模块的加载时间,并作为实验执行以下操作
(time (require 'runtime.account :reload-all))
其中runtime.account是我的根模块之一。
结果,我在第三方库模块的加载时间上没有看到任何差异:/。
也许您可以提供有关决定加载类文件或clj文件机制的详细信息以及一些用于监控此活动的途径?
谢谢!