【问题标题】:Why doesn't type hinting improve performance in this function?为什么类型提示不能提高此功能的性能?
【发布时间】:2026-01-09 09:40:01
【问题描述】:

代码如下:

(defn first-char-of-either [^String a  ^String b]
  (.substring (or a b) 0 1))
(defn first-char-of-either1 [^String a  ^String b]
  (.substring ^String (or a b) 0 1))
(time (dorun (repeatedly 1000000 #(first-char-of-either  nil "abcde"))))
(time (dorun (repeatedly 1000000 #(first-char-of-either1 nil "abcde"))))

这种情况下的类型提示根本没有提高性能,为什么?

【问题讨论】:

  • 不确定但可能是因为substringjava.lang.String 方法,因此编译器已经知道它是一个字符串?
  • 编译器无法保证运行时可能存在哪些类和方法,所以它无法知道substring是只存在于String的方法。

标签: performance clojure type-hinting


【解决方案1】:

类型提示仅在 Clojure 编译器无法推断类型时提高运行时性能。在first-char-of-either函数中,(or a b)表达式的or是一个宏,展开成这样。

(let* [or__3975__auto__ a] (if or__3975__auto__ or__3975__auto__ b))

因为 Clojure 编译器知道 ab 都具有 String 类型,所以它可以推断出 (or a b) 的结果类型,而不需要对 (or a b) 进行额外的类型提示。

总而言之,您不必在 Clojure 编译器可以推断类型的地方添加类型提示。您可以通过打开*warn-on-reflection* 来检查 Clojure 编译器是否可以成功推断类型。

【讨论】: