檢測對象是否是Clojure中的Java基元數組的最佳方法是什麼?測試對象是否是Clojure中的Java基元數組
我之所以需要這個是做一些特殊處理的基本數組,這可能看起來像:
(if (byte-array? object)
(handle-byte-array object))
它的代碼相當性能敏感的一塊,所以我寧願避免反光,如果儘可能。
檢測對象是否是Clojure中的Java基元數組的最佳方法是什麼?測試對象是否是Clojure中的Java基元數組
我之所以需要這個是做一些特殊處理的基本數組,這可能看起來像:
(if (byte-array? object)
(handle-byte-array object))
它的代碼相當性能敏感的一塊,所以我寧願避免反光,如果儘可能。
你可以使用反射一次是從名稱獲取類,緩存這一點,然後 其餘比較於
(def array-of-ints-type (Class/forName "[I"))
(def array-of-bytes-type (Class/forName "[B"))
...
(= (type (into-array Integer/TYPE [1 3 4])) array-of-ints-type)
true
不錯,就像緩存基本數組類一樣。雖然它確實有點讓我覺得它們還沒有在Java的某個地方定義過! – mikera 2012-02-01 04:26:09
,他們想出了這個名字:「[I」在那...... – 2012-02-01 04:30:11
'「[J''因爲'長'更加可愛,不是嗎?另外,無論誰在'.toString'中提出了無與倫比的開頭括號,都會返回值,只要我知道他們的名字,我的乾草叉就會準備好。它一直讓我失去信任,更不用說[對我的心理的影響](http://xkcd.com/859/)。 (替換所有相關案例的'print-method'可能不可行 - 我目前的直覺是* not *)。 – 2012-02-01 04:51:14
(defn primitive-array? [o]
(let [c (class o)]
(and (.isArray c)
(.. c getComponentType isPrimitive))))
對於特殊情況下,你可以使用類似以下內容:
(defn long-array? [o]
(let [c (class o)]
(and (.isArray c)
(identical? (.getComponentType c) Long/TYPE))))
所有的祕密都是裸露的:http://docs.oracle.com/javase/6 /docs/api/java/lang/Class.html – Bill 2012-02-01 04:46:01
或純老instance?
:
(instance? (RT/classForName "[B") thing)
你使用了什麼別名用於'RT'?你的意思是'(Class/forName「[B」)'對嗎? – 2013-12-21 05:00:22
@DavidJames RT是clojure.lang.RT。 – kotarak 2015-05-07 17:02:33
正如指出亞瑟Ulfeldt,您可以使用Class/forName
,例如,喜歡這裏:
(def byte_array_class (Class/forName "[B"))
(defn byte-array? [arr] (instance? byte_array_class arr))
如果你想避免像"[B"
魔術字符串緩存類時,你可以申請class
到現有陣列對象:
(def byte_array_class (class (byte-array [])))
更簡單:'(def byte-array-class(class(byte-array 0)))'。 (不要強調!) – 2013-12-21 05:02:40
要檢查的字節數組,而無需使用反射,你可以這樣做:
(def ^:const byte-array-type (type (byte-array 0)))
(defn bytes? [x] (= (type x) byte-array-type))
不完全確定爲什麼,但是您甚至可以用^:const
內聯字節數組類型。
道具所有其他答案。在這裏它是作爲一襯墊:
(def byte-array? (partial instance? (Class/forName "[B")))
對於其他原語,指http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getName%28%29(或Java規範)。或者只是做Gerrit建議的(type (xyz-array 0))
。具體來說,你可以使用:
"[Z" boolean array
"[B" byte array
"[C" char array
"[D" double array
"[F" float array
"[I" integer array
"[J" long array
"[S" short array
由於性能所提到的,這裏的運行(time (dotimes [_ 500000] (byte-array? x)))
的小基準測試結果,並與byte-array-class
def'd
(def byte-array? (partial instance? (Class/forName "[B")))
78.518335 msecs
(defn byte-array? [obj] (instance? byte-array-class obj))
34.879537 msecs
(defn byte-array? [obj] (= (type obj) byte-array-class))
49.68781 msecs
instance?
VS type
=實例?勝
partial
VS defn
= DEFN勝
但這些方法將可能不會在性能上的瓶頸。
不知道Clojure的代碼是什麼,但是你可以爲每個基元類型創建一個空數組,對這些數組調用getClass()並緩存結果。 Class對象對於每個原始類型的數組都應該是相同的 - 您可以使用object.getClass()比較緩存的對象。(getClass()不應該是一個緩慢的調用) – millimoose 2012-02-01 03:45:15