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

欢迎!请参见 关于 页面,了解更多此平台的信息。

+2
编译器
编辑

直接链接的全覆盖启用可能会破坏库,我无法控制哪些变量受到影响,但我仍想在到自己代码的部分提高性能。

以下内容可行吗?

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

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

1 个答案

0

可能会破坏库

怎么做?

重要的是在编译时这些编译器绑定被设置为什么。编译是在加载期间发生的,所以应该可以在这里变得聪明一些,但这将是复杂的。我认为在某个地方还有关于如何控制直接链接区域的询问。

“怎么会这样?”

在我看来,在反编译的代码中,根据Clojure文档,'direct-linking'编译器关键字尝试在可能的情况下启用直接功能调用,而不是通过变量进行间接调用。

假设我的Clojure代码使用了一些第三方Clojure库。
使用'lein uberjar',我可以在我的结果jar文件中看到第三方Clojure库的编译类文件。

如果我使用带有'-Dclojure.compiler.direct-linking=true'的'lein uberjar',那么有可能我打破了依赖于某些_runtime_全局变量重绑定魔法的第三方库?这些变量可能因直接链接而消失?
动态变量不会进行直接链接。
明白了

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

AFAIK,在启用直接链接时,alter-var-root会改变变量,但其引用已经被编译,所以调用点将不会受到影响,将继续使用编译后的直接功能调用

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

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

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

    ;; 库
    
    (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])))))
                                          
因此,我在此粘贴了一个启用命名空间直接链接的示例,以供参考。以防我完全忘记了这次对话,以后再次查找直接链接的答案 hahaha。

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