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

关于repetitive def和alter-var-root呢?

据我所知,当启用direct-linking时,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}]
       ,,,
       )
...