GHC 7.6 के लिए डॉक्स से :
[Y] ou अक्सर पहली जगह में विशेषज्ञ की आवश्यकता नहीं है। मॉड्यूल M को संकलित करते समय, GHC का ऑप्टिमाइज़र (-O) स्वचालित रूप से M में घोषित प्रत्येक शीर्ष-स्तरीय अतिभारित फ़ंक्शन पर विचार करता है, और इसे विभिन्न प्रकारों के लिए माहिर करता है जिस पर इसे M. कहा जाता है। ऑप्टिमाइज़र प्रत्येक आयातित INLABLE ओवरलोड फ़ंक्शन को भी मानता है, और इसे विभिन्न प्रकारों के लिए माहिर करता है जिस पर इसे एम कहा जाता है।
तथा
इसके अलावा, एक फ़ंक्शन च के लिए एक विशेष प्रज्ञा दिया जाता है, जीएचसी स्वचालित रूप से किसी भी प्रकार के वर्ग-अधिभारित कार्यों के लिए विशेषज्ञता का निर्माण करेगा जिसे एफ कहा जाता है, यदि वे विशेष मॉड्यूल के रूप में एक ही मॉड्यूल में हैं, या यदि वे शामिल नहीं हैं; और इतने पर, सकर्मक रूप से।
तो जीएचसी को स्वचालित रूप से कुछ / सबसे / सभी (?) कार्यों INLINABLE
को एक प्रज्ञा के बिना चिह्नित करना चाहिए , और यदि मैं एक स्पष्ट प्रज्ञा का उपयोग करता हूं, तो विशेषज्ञता सकर्मक है। मेरा सवाल है: क्या ऑटो- स्पेशलाइज़ेशन ट्रांजिटिव है?
विशेष रूप से, यहाँ एक छोटा सा उदाहरण है:
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
जीएचसी कॉल करने में माहिर है plus
, लेकिन उस उदाहरण में विशेषज्ञ नहीं है जो प्रदर्शन को मारता है।(+)
Qux
Num
हालांकि, एक स्पष्ट व्यावहारिक
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}
डॉक्स संकेत के रूप में सकर्मक विशेषज्ञता में परिणाम है, इसलिए (+)
विशिष्ट है और कोड 30x तेज (दोनों के साथ संकलित -O2
) है। क्या यह अपेक्षित व्यवहार है? क्या मुझे केवल (+)
एक स्पष्ट प्रज्ञा के साथ विशेष रूप से पारगमन की उम्मीद करनी चाहिए ?
अपडेट करें
7.8.2 के लिए डॉक्स नहीं बदले हैं, और व्यवहार समान है, इसलिए यह प्रश्न अभी भी प्रासंगिक है।
plus
गया था ) सिमोनज ने संकेत दिया कि टिकट कोड के साथ कुछ इनलाइनिंग चल रही थी, लेकिन कोर से मेरे उदाहरण से पता चलता है कि कोई भी फ़ंक्शन इनबिल्ड नहीं था (विशेष रूप से, मैं दूसरे कंस्ट्रक्टर से छुटकारा नहीं पा सकता था, अन्यथा जीएचसी इनबिल्ड सामान)। Foo
plus (Bar v1) = \(Bar v2)-> Bar $ v1 + v2
, ताकि कॉल साइट पर एलएचएस पूरी तरह से लागू हो? क्या यह इनबिल्ड हो जाता है और फिर स्पेशलाइजेशन किक करता है?
plus
रूप से उन लिंक के कारण विशेष रूप से पूरी तरह से लागू होने के लिए कॉल था , लेकिन वास्तव में मुझे कम विशेषज्ञता प्राप्त हुई: कॉल plus
या तो विशेष नहीं थी। मेरे पास इसके लिए कोई स्पष्टीकरण नहीं है, लेकिन यह एक और प्रश्न के लिए छोड़ने का इरादा था, या आशा है कि यह इस एक के जवाब में हल हो जाएगा।