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_ 绑定的全局变量魔法的第三方库吗?这些魔法可能会因为直接链接而消失?
动态变量不进行直接链接。
我明白了

def 和 alter-var-root 的重复性有什么用?

据我所知,一旦启用 direct-linking,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])))))
                                          
所以,我贴了一个如何在命名空间中启用直接链接的例子,以防万一。以防我完全忘了这次对话,以后再次查看直接链接。

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