我正在寫取決於多種常量的Clojure的代碼不變。什麼是Clojure的等價的「公共靜態最後的」在Java中
它們將在嚴格的內部循環中使用,所以重要的是它們將盡可能有效地被Clojure編譯器+ JVM組合使用和優化。爲了同樣的目的,我通常會在Java中使用「public static final」常量。
什麼是聲明這些的最佳途徑?
我正在寫取決於多種常量的Clojure的代碼不變。什麼是Clojure的等價的「公共靜態最後的」在Java中
它們將在嚴格的內部循環中使用,所以重要的是它們將盡可能有效地被Clojure編譯器+ JVM組合使用和優化。爲了同樣的目的,我通常會在Java中使用「public static final」常量。
什麼是聲明這些的最佳途徑?
我認爲def
- 全局命名空間中的事物大概就近了。
如上所述使用def或atom,請記住,數據是不可變的,所以如果你在列表中聲明瞭一些常量,它們不會改變。
如果他想要一些可變的東西,他會要求一個常數,無論如何,你一定會用原子列出一個列表。你會製作一個原子列表或參考列表。 – nickik 2010-07-19 12:46:41
有沒有defconst
,所以只使用全局def是慣用的;就優化而言,JIT會讓事情變得更快。
如果真的,真的,真的需要恆定的地方(我相信JIT會注意到這個值是不變的並且做正確的事情),但是你可以使用宏。
(defmacro my-constant [] 5)
這是相當醜陋的,但性能關鍵代碼將永遠是醜陋的,我猜。
(do-stuff (my-constant) in-place)
不過要注意你把什麼放入宏中!我不會超過一些文字常量。尤其不是對象。
如果只是使用def
不夠快,您可以嘗試在進入緊密循環之前創建一個綁定別名,以避免每次都經歷一次var。
謝謝 - 所以我正確地說,如果你不這樣做,那麼每次訪問常量時它都會取消引用var。 – mikera 2010-07-19 19:38:13
我相信Clojure 1.3(或者可能是1.4)允許你在def
上放置一個^:constant
標籤,這意味着編譯器應該是一個常量,並且所有的引用都應該在編譯時解析。
顯然,這是Clojure的1.3,這是^:const
,不^:constant
。請參閱How does Clojure ^:const work?獲取摘要。
添加:const的元數據將導致它在編譯時被內聯,看到答案由@amalloy。全球決策是變數,它們雖然接近,但可以在運行時調整並得到解決。 – deterb 2012-02-07 20:52:29