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

欢迎!有关此功能的更多信息,请参阅 关于 页面。

0
打印
运行此示例代码

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(in-ns 'clojure.pprint)


(println "使用原生 str 输出基本输出。")
(time
 (doseq [i (range 1000)]
   (apply str (interpose "," [1 2 3]))))


(println "测试 1 - 原生 cl-format")
(time
 (doseq [i (range 1000)]
   (clojure.pprint/cl-format nil "~{~D~^,~}" [1 2 3])))
;; ==> "执行时间: 231.345 毫秒"


(println "测试 2 - 调用编译格式")
(def myx
  (compile-format  "~{~D~^,~}"))

(time
 (doseq [i (range 1000)]
   (clojure.pprint/cl-format nil myx [1 2 3])))



(println "测试 3 - 使用格式化工具")
(def myy
  (formatter  "~{~D~^,~}"))

(time
 (doseq [i (range 1000)]
   (myy nil myx [1 2 3])))



(time
 (dotimes (i 100000)
   (format nil  "~{~D~^,~}" '(1 2 3))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

它将打印类似以下内容

使用原生 str 输出基本输出。
"执行时间: 2.402 毫秒"
测试 1 - 原生 cl-format
"执行时间: 194.405 毫秒"
测试 2 - 调用编译格式
"执行时间: 87.271 毫秒"
测试 3 - 使用格式化工具
"执行时间: 199.318 毫秒"

所以原生 `str` 速度大约快 100 倍。

参照,在相同硬件上使用
SBCL Common Lisp,这个测试在 < 1 毫秒内运行。


这里至少有两个问题

 1. cl-format 函数开始于如下行:

    let [compiled-format (if (string? format-in) (compile-format format-in) format-in)

   但是没有 API 可以传入编译格式到其中;因为编译格式
   是一个私有函数,所以无法广泛使用,因此这有点无用。

 2. 即使使用预编译的格式化工具也过于缓慢。


建议的解决方案:没有其他解决方案,也许应该警告用户这个
函数根本不适用于密集循环,并且只能用于
美化用户输入字符串等。

谢谢

2 个回答

0
参考: https://clojure.atlassian.net/browse/CLJ-1950(由 alex+import 报告)
0
by

这个问题似乎可以通过将compile-format设为公开来解决。关于compile-format的文档字符串建议将其用作提高性能的一种方式;将返回的编译块传递给cl-format(代替格式字符串)似乎是按预期正常工作的。或许只是忘记将该函数标记为私有?

by
虽然compile-format有所帮助,但与clojure.core/format相比,效果相去甚远。

与Common Lisp的format不相匹配是此线程的核心问题。

https://www.reddit.com/r/lisp/comments/qho92i/a_casual_clojure_common_lisp_codeperformance/

cl-format需要重写以消除很多低效率;尤其是使用持久结构的独家使用,而Common Lisp的format则不行。我大约在编写这个帖子的时候开始思考这个问题,但并没有取得太大的进展。
...