Gönderen docs ghc 7.6 için:
[Y] Genellikle ilk etapta UZMANLIK pragmasına bile ihtiyaç duymazsınız. Bir modül M derlenirken, GHC'nin iyileştiricisi (-O ile) M'de bildirilen her üst düzey aşırı yük fonksiyonunu otomatik olarak dikkate alır ve M'de çağrıldığı farklı tipler için uzmanlaşır. İyileştirici ayrıca içe aktarılan her INLINABLE aşırı yük fonksiyonunu, ve M'de adlandırıldığı farklı türler için uzmanlaşmıştır.
ve
Dahası, bir f işlevi için ÖZELLEŞTİRİLMİŞ pragma verildiğinde, GHC, SPECIALIZE pragma ile aynı modüldeyse veya INLINABLE ise, f tarafından çağrılan tüm tip-aşırı yüklenmiş işlevler için otomatik olarak uzmanlıklar oluşturur; ve benzeri, geçişli.
Bu yüzden GHC, pragma olmadan işaretlenmiş bazı / çoğu / tüm (?) İşlevlerini otomatik olarak uzmanlaştırmalıdır ve eğer açık bir pragma kullanırsam, uzmanlık geçişlidir. Sorum şu: oto- uzmanlaşma geçişli mi?INLINABLE
Özellikle, küçük bir örnek:
Main.hs:
import Data.Vector.Unboxed as U
import Foo
main =
let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int)
(Bar (Qux ans)) = iterate (plus y) y !! 100
in putStr $ show $ foldl1' (*) ans
Foo.hs:
module Foo (Qux(..), Foo(..), plus) where
import Data.Vector.Unboxed as U
newtype Qux r = Qux (Vector r)
-- GHC inlines `plus` if I remove the bangs or the Baz constructor
data Foo t = Bar !t
| Baz !t
instance (Num r, Unbox r) => Num (Qux r) where
{-# INLINABLE (+) #-}
(Qux x) + (Qux y) = Qux $ U.zipWith (+) x y
{-# INLINABLE plus #-}
plus :: (Num t) => (Foo t) -> (Foo t) -> (Foo t)
plus (Bar v1) (Bar v2) = Bar $ v1 + v2
GHC çağrısı uzmanlaşmış plus
, ama yok değil uzmanlaşmak (+)
içinde Qux
Num
performans öldürür örneği.
Ancak, açık bir pragma
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}
dokümanlar belirtildiği gibi geçişsel uzmanlaşma ile sonuçlanır , bu yüzden (+)
uzmanlaşmıştır ve kod 30x daha hızlıdır (her ikisi de derlenmiştir -O2
). Bu beklenen davranış mı? Sadece (+)
açık bir pragma ile geçici olarak uzmanlaşmayı beklemeli miyim ?
GÜNCELLEME
7.8.2 için dokümanlar değişmedi ve davranış aynı, bu yüzden bu soru hala alakalı.
plus
yapıldı değil INLINABLE ve 2 olarak işaretlenen) simonpj bazı bilet koduyla oluyor inlining, ama belirtti çekirdek örneğim, işlevlerin hiçbirinin satır içi olmadığını gösterir (özellikle ikinci Foo
yapıcıdan, aksi takdirde GHC satır içi öğelerinden kurtulamadım ).
plus (Bar v1) = \(Bar v2)-> Bar $ v1 + v2
LHS'nin çağrı sitesinde tam olarak uygulanması için tanımladığınızda ne olur ? Satır içi olur ve uzmanlaşma devreye girer mi?
plus
özellikle bu bağlantılar nedeniyle tamamen başvurmak için çağrı vardı , ama aslında daha az uzmanlık aldım : çağrı plus
da uzman değildi. Bunun için bir açıklamam yok, ama başka bir soru için bırakmayı ya da bunun bir cevabında çözüleceğini umuyordum.