2011-02-05 52 views
8

我需要使用一個類型(任何類型)作爲一個標記在一個隱式的類型參數,以區別於另一個隱式。這很奇怪,但這可能是另一個問題。斯卡拉最便宜的類型是什麼?

因爲我可以使用任何類型的,我想用最便宜的之一,在內存佔用初始化時間的條款。在這種情況下,它可能不會影響性能,但問題很有趣:哪一個是Scala最便宜的類型?

在Java中,答案顯然是java.lang.Object。但斯卡拉有一些「有趣」的類型:Any,AnyVal類型和底部類型可能優化他們周圍。 Nothing類型不能被實例化,所以它被排除在這個比較之外。

+3

有趣的是,我會說在java中最便宜的類型是一個簡單的int。 – Yahel 2011-02-05 08:08:00

+0

我不知道這是多麼「便宜」,但沒有什麼可用:`def x(_:Nothing)=(); x(null.asInstanceOf [Nothing])`只是*不*嘗試使用Nothing :-) – 2011-02-05 08:21:27

+0

在「根」問題上看到一個問題也很有趣。 – 2011-02-05 08:24:53

回答

3

如果您選擇AnyAnyVal,那麼您傳遞的任何基元都將被裝箱,因此可能已經過期。

AnyRef確實是一個不錯的選擇。

如果沒有進行任何類型參數化,那麼「基元」也是很好的選擇 - 例如BooleanInt

還有Null,這是一個非常有趣的選擇,因爲它根本不分配任何東西,而且它是一個文字,所以它必然是快速的。不知道你到底在幹什麼,我不知道這是否是有效的選擇。

另一個有趣的選項是java.lang.Integer(使用靜態方法valueOf),因爲它保證小值的引用相等(您必須檢查文檔以查看精確範圍),這意味着不涉及分配。

1

既然Scala運行在Java之上,我會假設同樣的答案也適用於Scala世界。 Any類型的Scala對象只是某種Java對象。

在Java中,我認爲像int,short或byte這樣的原始類型比Object更便宜,但這些類型可能會被包裝/裝箱在Scala中。 (不是100%地肯定,雖然。)

更新

如果由於某種原因,它必須是一個對象,而不是原始類型,字符串可能是最好的,因爲字符串在虛擬機實習。所以在整個應用程序中通常只有一個對象實例。

4

我不知道我得到你的意思「最廉價型」 ......在Java中的內存方面最廉價的數值類型可以是字節什麼,但是從性能POV Java的優化與詮釋工作。事實上,很多(或大多數)語言都經過優化,可以與int(甚至是DB引擎)一起工作。 Scala是JVM語言,所以我會說最好使用int。

更新:如果問題是關於「標記/未標記」適合的數據類型,我會使用布爾原語。

如果您在斯卡拉 程序boolean類型,你實際上會得到 類型是scala.Boolean。或者如果你輸入 浮點數,你會得到scala.Float。當您將您的Scala代碼編譯爲Java 字節碼時,Scala會將這些類型編譯爲 這些類型爲Java的原始類型 ,在可能的情況下獲得Java基本類型的性能 。

沒有什麼是任何,這是一種在Java對象,任何對象需要更多的內存比任何基本類型

而且順便說一句,使用布爾作爲標記是很自然的,它提高了代碼的可讀性(和因此支持,他人的理解)。即使有其他的東西,更優化我不會做過早的優化,並會選擇布爾值。

13

這取決於你確切的問題,但是在Scala中最便宜的構造 - 或者任何語言 - 都必須是一個根本不存在的構造......(至少,不是在運行時)

允許我引入Phantom Types,允許編譯器靜態地執行正確的操作,但在它們到達JVM之前被清除爲空。

以類似的方式,您可以輕鬆地區分兩個不同類型的對象而不需要任何標記字段。這是case object的好選擇,並且與模式匹配一​​起工作得非常好。

0

當您運行包裝程序的方法調用時,Scala會封裝基本類型,而原始類型不會實現。所以即, 1024 * 512未被包裝,但在1024.toInt * 512中,1024被包裝。