2012-03-14 70 views
43

documentation狀態:是否有任何理由不使用INLINABLE pragma作爲函數?

一個吱 - #可以內聯F# - }在函數f編譯有以下行爲:

  • 雖然INLINE說: 「請行內我」 時,可以內聯說: 「隨時聯繫我,使用您的判斷力」。換句話說,選擇留給GHC,它使用與無雜注函數相同的規則。與INLINE不同,該決定是在呼叫站點進行的,因此將受到內聯閾值,優化級別等的影響。

  • 與INLINE一樣,INLINABLE編譯指示保留用於內聯目的的原始RHS的副本,它在接口文件中,不管RHS的大小如何。

  • 使用INLINABLE的一種方法是與內聯特殊功能(第7.18節「特殊內置功能」)結合使用。內聯調用f非常難以內聯f。爲了確保f可以內聯,最好將f的定義標記爲INLINABLE,以便GHC保證揭示展開,而不管其大小如何。此外,通過將f註釋爲INLINABLE,您可以確保f的原始RHS被內聯,而不是GHC的優化器生成的任何隨機優化版本。如果將函數f標記爲INLINABLE,那麼隨後可以在另一個模塊中進行SPECIALIZE(參見第7.16.8節「SPECIALIZE編譯指示」)。

  • 與INLINE不同,可以在遞歸函數上使用INLINABLE雜注。最主要的原因做這樣允許以後使用專門

什麼是它的缺點嗎?

它使接口文件更大,更大嗎?它是否會使編譯速度變慢?

是否有任何理由我不應該在我寫的每個導出函數上放置一個INLINABLE編譯指示?是否有任何理由GHC不會在我寫的每個導出函數上放置一個INLINABLE編譯指示?

回答

49

有使用可以內聯,而不是使用編譯所有之間的三點區別:

  • 沒有可以內聯,那雲在接口文件中的定義是後優化代碼,而與可以內聯,它是你寫的代碼(或多或少)。特別是,如果沒有INLINABLE,GHC可能會將其他函數內聯到函數的定義中。

  • 如果沒有INLINABLE,GHC將會從接口文件中省略定義,如果它太大。如果其他功能插入右側,這可能會輕易超過極限。

  • INLINABLE還打開了一些巧妙的機制,它們在使用它們時會自動專用重載函數,並與其他模塊共享專用版本,這些模塊可以通過傳輸方式導入創建專用版本的模塊。

+9

我想了解實際的後果。第一點意味着函數沒有內聯的地方,它會使用未優化的代碼並且速度較慢?或者如果它被內聯,它會變慢,但RULES不會觸發?或者它有時會更快,有時會慢一些?關於第二點,將其包含在除磁盤空間以外的接口文件中是否有任何缺點?它們能變得如此之大以至於出現問題(磁盤很大)?重申:第三點,有什麼理由說它不是一個沒有光彩的好東西?它會導致代碼量膨脹的問題? – glaebhoerl 2012-03-14 21:12:54

+4

我故意避免談論實際的後果,因爲大部分我不確定:-)我說服西蒙PJ添加了INLINABLE,因爲我想要一個不會導致太多代碼膨脹的INLINE變體,通過使用GHC已經非常複雜的啓發式關於何時內聯。要回答你的第一個問題:不,還會有編譯到原始模塊中的函數的優化版本(與INLINE一樣),這將用於未內聯的調用。在界面中包含大量的函數定義可能會降低速度。 – 2012-03-15 08:39:31

+0

嗯,好吧。如果有關於何時使用它以及何時不使用它的指導方針會很好,但我想我必須進行試驗。 :) – glaebhoerl 2012-03-15 11:59:03

相關問題