为啥类型提示不能提高此功能的性能?
Posted
技术标签:
【中文标题】为啥类型提示不能提高此功能的性能?【英文标题】:Why doesn't type hinting improve performance in this function?为什么类型提示不能提高此功能的性能? 【发布时间】:2015-07-16 20:40:57 【问题描述】:代码如下:
(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"))))
这种情况下的类型提示根本没有提高性能,为什么?
【问题讨论】:
不确定但可能是因为substring
是java.lang.String
方法,因此编译器已经知道它是一个字符串?
编译器无法保证运行时可能存在哪些类和方法,所以它无法知道substring
是只存在于String的方法。
【参考方案1】:
类型提示仅在 Clojure 编译器无法推断类型时提高运行时性能。在first-char-of-either
函数中,(or a b)
表达式的or
是一个宏,展开成这样。
(let* [or__3975__auto__ a] (if or__3975__auto__ or__3975__auto__ b))
因为 Clojure 编译器知道 a
和 b
都具有 String
类型,所以它可以推断出 (or a b)
的结果类型,而不需要对 (or a b)
进行额外的类型提示。
总而言之,您不必在 Clojure 编译器可以推断类型的地方添加类型提示。您可以通过打开*warn-on-reflection*
来检查 Clojure 编译器是否可以成功推断类型。
【讨论】:
以上是关于为啥类型提示不能提高此功能的性能?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在引入属性类型提示时突然收到“在初始化之前不能访问类型属性”错误?
为啥 Clojure 编译器不会为不正确的类型提示抛出错误?
为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'