2010-10-20 72 views
5

假設我想要一個類如Java Date。它唯一的數據成員是一個漫長的代表自1970年以來Scala中的「裝箱」原始類型的開銷

毫秒會/莫非只是做一個新的Scala類型的任何性能優勢:

type PrimitiveDate = Long 

然後,你可以通過使用隱式添加方法轉換,就像使用RichInt進行int處理一樣。這種將原始類型「裝箱」成一個豐富的類是否涉及任何開銷(創建類)?基本上,你可以只是一個靜態方法

def addMonth(date: PrimitiveDate, months: Int): PrimitiveDate = date + 2592000000 * months 

,並讓類型系統弄清楚,它具有當d addMonth 5 出現在代碼中得到應用。

編輯

看來你寫type PrimitiveDate = Long創建別名不是由Scala編譯器執行。是否正在創建一個適當的類,並附上Long,這是在Scala中創建強制類型的唯一方法?

您認爲能夠爲原始類型創建強制類型別名有多大用處?

回答

10

好,escape analysis應該意味着最新的JVM實際上沒有爲了調用addMonth方法來建立豐富的包裝

程度此實際上發生在實踐顯然將取決於多少運行熱點 JVM的決定,這些方法在創建對象加入到。當轉義分析沒有發生時,顯然JVM將不得不在包裝類的新實例中「框」(如您所說)Long。它不涉及「創建類」 - 它涉及「創建一個類的實例」。這種情況下,被短命然後將GC-D立即,所以開銷(雖然小)是:

  • 爲實例內存分配
  • GC-ING實例

這些如果你肯定寫了非常低延遲的代碼,你試圖最小化垃圾創建(在一個緊密的循環中),那麼顯然只會是任何類型的問題。只有你知道這是否是這種情況。至於這種方法是否適合你(逃避分析來幫助你),你必須在野外進行測試。對於這種事情,微型基準很難寫出來。


我不太喜歡這些類型別名是一個公共API的部分原因是,Scala並沒有真正執行它們爲嚴格,因爲我想。例如:

type PrimitiveDate = Long 
type PrimitiveSpeed = Long 
type Car = String 
type Meeting = String 

var maxSpeeds : Map[Car, PrimitiveSpeed] = Map.empty 

//OOPS - much too easy to accidentally send the wrong type 
def setDate(meeting : Meeting, date : PrimitiveDate) = maxSpeeds += (meeting -> date) 
+0

「執行別名」的好處。那是我想知道的一件事。所以沒有辦法在scala中爲原始類型創建適當的類型別名? – ziggystar 2010-10-20 14:56:58

+1

@ziggystar - 沒有沒有。我傾向於將類型別名用於以下兩種情況之一:像凱文那樣的私人內部東西在下面談論;包對象導入(即爲什麼'List'似乎仍是在'scala'包) – 2010-10-20 15:10:12

+0

我覺得萬里薩賓想出了一個優雅和高性能[解決方案](https://gist.github.com/milessabin/89c9b47a91017973a35f)在提出這個問題後11個月。 – itsbruce 2015-08-24 15:30:32

4

你還沒有真正在給定的例子創建了一個新的類型,它只是對以前存在的長型的別名。

這是一個技術我使用經常對付笨重嵌套連接。例如,我的別名爲type Grid = Seq[Seq[Int]],以避免必須一遍又一遍地指定Seq[Seq[Int]]以獲取各種參數。

你可以很愉快地傳遞到Long採取PrimitiveDate方法的方法,雖然你的優勢在於該代碼是更好的自我記錄。

如果你確實想創建一個新的類型與強制類型安全,便捷的模式匹配,我會使用的情況下類:

case class PrimitiveDate(value:Long) 

和潛在的,甚至提供一個隱含的龍=> PrimitiveDate轉換爲了方便。你問的這個問題

3

後11個月,萬里薩賓發現Scala中創建unboxed newtypes的一個非常簡單的,優雅的和高性能的方式。與類型別名不同,類型標籤被強制執行。原始類型需要最少的樣板(每個原語一行)來提供專業化。

一年後,他加入這個more polished and robust versionShapeless。這個概念簡單而簡潔,足以在項目中複製,而不需要添加無形體,如果你不想要其他優秀的庫。

當然,你和誰回答您的問題可能知道這個祕密的人,但它是值得加入這裏,因爲這仍然是一個重要的問題。

+0

我想這些裝箱newtypes類似於上述[這裏]幻像類型(http://stackoverflow.com/questions/6358651/marking-primitive-types-with-phantom-types-in-scala/6360260#6360260),對? – ziggystar 2015-08-24 19:00:25