Geçişlilik Oto-Uzmanlık DZD içinde
DZD 7.6 the docs:
[Y]ou sık sık hatta ilk etapta pragma UZMANLAŞMAK gerek yok. Derleme, modül M, DZD bu doktoru (- O) otomatik olarak dikkate alır her üst düzey işlevde ilan M ve uzmanlaşmış bunun için farklı türleri olan bu denilen M. doktoru da dikkate alınan her İNLİNABLE işlevde ve uzmanlaşmış bunun için farklı türleri olan denir, M.
ve
Ayrıca, belirli bir UZMANIM pragma için bir fonksiyon f, DZD otomatik olarak oluşturmak uzmanlık için her tür-sınıf-aşırı yüklenmiş fonksiyonlar f, eğer onlar aynı modülü olarak UZMANLAŞMAK pragma, ya da eğer onlar İNLİNABLE; ve bu yüzden, geçişli.
DZD otomatik olarak some/most/all(?) fonksiyonlar INLINABLE
işaretli uzmanımolmadanbir pragma, ve eğer açık bir pragma kullanırsam, uzmanlık geçişli. Benim sorum:
oto-uzmanlık geçişli?
Özellikle, burada küçük bir örnek:
Ana.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
DZD plus
, çağrı uzmanlaşmış ama yokdeğilperformans öldürürQux
Num
örnek ( )
uzmanım.
Ancak, açık bir pragma
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}
sonuçlarıgeçişlidoktorlar gibi uzmanlık ( )
özel ve kodu 30 x daha hızlı, (her ikisi de -O2
ile derlenmiş) gösterir. Bu beklenen bir davranış mı? Sadece ( )
geçişli açık bir pragma ile özel olmasını nasıl bekleyebilirim?
GÜNCELLEME
7.8.2 için doktorlar değişmedi ve aynı davranıştır, bu soru hala geçerlidir.
CEVAP
Anahtarı tek bir birleştirme ve tek bir yerde tüm yazı ya da zaman içinde biriken olsun.
Verdiğin örneğin, açıkça StringBuilder kullanarak anlamı yok. (İlk davanız için derlenmiş koda bak.)
Ama eğer bir döngü içinde dize örneğin, eğer bir bina, StringBuilder kullanın.
Açıklığa kavuşturmak için, hugeArray dizeleri, kod binlerce içerir varsayarak bu gibi:
...
String result = "";
for (String s : hugeArray) {
result = result s;
}
zaman ve bellek - yazık oldu çok ile göre:
...
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
sb.append(s);
}
String result = sb.toString();
Nasıl farklı bir Ruby döngü içinde ilk...
Nasıl dizin Python içinde olup olmadığ...
Nasıl programlı göre Düzen içinde bir ...
Nasıl doğru erişim için `` / bu içeriğ...
Unıx '' bir dizin içinde cd ...