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

欢迎!请参阅关于页面了解有关这一工作的更多信息。

0
编译器
已关闭

使用 core/proxy 为 Java 类生成代理会在生成的类文件中产生不可预测的方法顺序。
这对需要可重复构建(在执行 AOT 时)来说是个问题。

具体来说,我在 Docker 内运行 Clojure,并希望我的应用镜像层尽可能小,与 Java 开发者(使用 Meta-inf 类路径和 lib 目录)生成的镜像层大小相当。不管怎样,为了使其正常工作,让所有依赖项(包括作为 AOT 部分编译的依赖项)都在一个单独的层上,我需要每次构建时编译我的应用程序依赖项代理的输出都相同。这可以减少构建时间、镜像推送时间、镜像拉取时间和容器调度时间。

展示问题的示例代码(您需要运行几次才能看到问题)。

https://github.com/kipz/predictable-proxies

原因:我已经追踪到这里使用了一个未排序的映射

https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L186

方法:使用一个有排序的映射,按键的哈希排序(键是一个方法名、参数类型的序列和返回类型向量)。

补丁:CLJ-1973-v5.patch

审核:由 Alex Miller 质量

已关闭,备注: 在 1.11.0-beta1 中发布

10 条回答

0

评论由:kipz 添加

使用 sorted-map 的补丁

0

评论者为:alexmiller

我认为你可以参考《https://clojure.org/guides/comparators》中的建议来为这次补丁编写一个更简单的比较器。

0

评论由:kipz 添加

已按要求简化比较器。

0

评论者为:alexmiller

我认为你可能丢失了排序后的集合。

0

评论由:kipz 添加

在不同分支之间的复制粘贴错误。这次已测试。

0

评论由:kipz 添加

现在对 'let' 的格式进行了更一致的调整

0

评论者为:alexmiller

虽然这可能没问题,但最好还是使用Clojure的 'hash' 函数而不是Java的 'hashCode' 函数。由于映射本身是基于 'hash' 进行哈希的,这似乎更为合适。

0

评论由:kipz 添加

如请求,已使用Clojure的 'hash' 函数。

感谢Alex - 还学到了关于布尔比较器的内容!

0

评论者为:alexmiller

请注意,这种排序可能会随着Clojure或JVM版本的不同而发生变化,因为这些版本之间没有哈希保证。目前进行预筛选。

0
参考:https://clojure.atlassian.net/browse/CLJ-1973(年由kipz报告)
...