请在2024年Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以获得更多关于如何工作的信息。

+2
编译器
编辑

无差别地启用直接链接可能会破坏库,我无法控制库中哪些变量受到影响,但我仍然希望在至少我自己的代码部分提高性能。

以下内容会工作吗?

(binding [clojure.core/*compiler-options* 
  {:direct-linking true}]
  ,,,
  )

这里是文档: https://docs.clojure.org/clojure.core/*compiler-options*

1 个答案

0

可能会破坏库

怎么做?

重要的是编译发生时编译器绑定设置为什么。编译发生在加载期间,因此应该可以在一些情况下变得非常巧妙,但这将是巧妙的。我认为在其他地方还有一个问题,关于如何增加对直接链接位置的更多控制。

"怎么会这样?”

根据我的观察,在反编译的代码中,以及根据clojure文档,'direct-linking'编译器允许尽可能直接调用函数,而不是通过var进行间接调用。

假设我有一些使用第三方clojure库的clojure代码。
在使用“lein uberjar”后,我可以看到在我的结果jar文件中包含第三方clojure库的编译后的类文件。

如果我使用“lein uberjar”加上“-Dclojure.compiler.direct-linking=true”,那么我是否可能破坏依赖某些_runtime_重新绑定全局vars魔法的第三方库呢?这些魔法可能会因为直接链接而消失?
动态vars不会进行直接链接。
明白了

有关重复的def和alter-var-root呢?

AFAIK(据我所知),在直接链接启用的情况下,alter-var-root改变var,但其引用已经编译,所以调用点不会受到影响,并继续使用编译后的直接函数调用

正确吗?
— 可以破坏库
— 怎么做?

是的,我有点困惑,弄错了。我的意思是,当整个代码库启用直接链接时,与库交互时可能会有问题。

第一种情况可能不太可能发生,但库可能期望用户以不同的方式实现协议并重新定义一个实例,或者我们可能出于某种原因想要这样做。

    ;; 图书馆
    
    (defprotocol MyProtocol
      (my-function [this]))
    
    (def my-instance (reify MyProtocol
                          (my-function [this] (println "hello"))))
    
    
    ;; 应用
    
    ;; 我们不能重新定义 my-instance
    ;; 我们也不能将其设置为 ^:redef,因为它在库中

第二种情况是我们正在处理库,并且忘记标记一个变量为 ^:redef,应用程序将无法看到其更改。

    ;; 图书馆
    (def my-var 10)
    ;; 我们尝试在编译完毕后更新它
    
    ;; 应用
    (defn use-var []
      (println my-var))

这两个例子可能有点牵强,我并没有一个确切的问题要问,“如何做到以下几点?”,但是直接链接仅被简要地记录,并没有解释如何以精细的方式处理,这就是我提问的原因。

Andray Shotkin查看了代码,并且显然这是可行的,代码确实是直接链接,没有使用变量。

    (binding [*compiler-options* {:direct-linking false}]
      (clj-java-decompiler.core/decompile (fn []
                                            (seq (map :x [1 2 3])))))
    
    (binding [*compiler-options* {:direct-linking true}])
      (clj-java-decompiler.core/decompile (fn []
                                            (seq (map :x [1 2 3])))))
                                          
所以,我在这里粘贴了一个如何为一个命名空间启用直接链接的例子,以防万一。以防我完全忘记了这次谈话,以后再次查找直接链接呢哈哈。

    (ns my-namespace
     (:require [clojure.core :as core]))
    
    (binding [core/*compiler-options*
              {:direct-linking true}])
       ,,,
       )
...