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

欢迎!请参见关于页面了解有关此功能的一些更多信息。

+2
Clojure

{{refer}} 在 {{require}}、{{use}} 和 {{refer-clojure}} 的情况下是基础,而且在将符号/变量的映射从命名空间复制到另一个命名空间的主要工作岗位上效率并不是特别高。

方法:可以进行的某些改进
- 直接到命名空间映射中,避免创建过滤的中间地图 (ns-publics)
- 使用 transient 构建引用的映射
- 替代一个个新引用的情况,构建所有更改的映射,然后执行 cas
- 对于 (:require :only ...) 的情况 - 只需遍历包含的变量并在其中查找匹配项,而不是遍历所有引用的变量

在所有这些工作中,肯定还有更多的重大变化(如不可变命名空间),这将进一步提高性能,但我尽量使得此次变更的范范围较小。

尽管单个 refer 的时间大大减少(对于 (refer clojure.core) 减少了约 50%,对于 :only 使用减少了约 90%),但 refer 只是更广泛的 require 加载时间的一个小部分,因此实际上的改进是适度的。

性能

| 在 new repl 中 expr | 1.7.0-beta3 | 1.7.0-beta3+补丁 |
| :-- | :-- | :-- | :-- |
| (in-ns 'foo) (clojure.core/refer 'clojure.core) | 2.65 毫秒 | 0.994 毫秒 |
| (in-ns 'bar) (clojure.core/refer 'clojure.core :only '(link: inc dec)) | 1.04 毫秒 | 0.113 毫秒 |
| (use 'criterium.core) | 0.877 毫秒 | 0.762 毫秒 |
| (require '(link: clojure.core.async :refer (>!! <!! chan close!))) | 3408 毫秒 | 3302 毫秒 |

补丁:clj-1730-2.patch

筛选备注

补丁似乎正确,但我们应考虑

  • {{if}} 替代 {{when}} 的非习惯用法使分支难以阅读
  • {{if}} 的非习惯用法缩进(两个分支都在同一行)难以阅读
  • 我认为不应该将未找到的作为 {{IllegalAccessError}},但原始代码已经这样做,所以...
  • 围绕 swap 的乐观并发循环 从未 放弃,这是否可行?

3 个答案

0

评论由:alexmiller 完成

补丁更新以解决第一次筛选评论。我实际上并没有发现第二个情况的任何案例?给我一个提示。

0

评论由:gshayban 完成

我怀疑这对最高性能的影响不大。鉴于所附的clojure.instant加载图片,这个补丁可能会缩短启动时间。

(使用Bytestacks创建的图片,今日记录了一个JDK11调试构建的配置文件)

0
参考: https://clojure.atlassian.net/browse/CLJ-1730 (由alexmiller报告)
欢迎使用Clojure问答社区,您可以在此提出问题,并从Clojure社区的成员那里获取答案。
...