हास्केल डेटा प्रकारों की मेमोरी पदचिह्न


124

हास्केल में कुछ डेटा प्रकार (ज्यादातर जीएचसी के साथ) के मूल्य को स्टोर करने के लिए आवश्यक मेमोरी की वास्तविक मात्रा मुझे कैसे मिल सकती है? क्या रनटाइम पर इसका मूल्यांकन करना संभव है (जैसे जीएचसीआई में) या क्या इसके घटकों से यौगिक डेटा प्रकार की स्मृति आवश्यकताओं का अनुमान लगाना संभव है?

सामान्य तौर पर, यदि स्मृति प्रकार की आवश्यकताएं aऔर bज्ञात हैं, तो बीजगणितीय डेटा प्रकारों की मेमोरी ओवरहेड क्या है:

data Uno = Uno a
data Due = Due a b

उदाहरण के लिए, स्मृति में कितने बाइट्स इन मूल्यों पर कब्जा करते हैं?

1 :: Int8
1 :: Integer
2^100 :: Integer
\x -> x + 1
(1 :: Int8, 2 :: Int8)
[1] :: [Int8]
Just (1 :: Int8)
Nothing

मैं समझता हूं कि कचरा संग्रहण में देरी के कारण वास्तविक मेमोरी आवंटन अधिक है। यह आलसी मूल्यांकन के कारण काफी भिन्न हो सकता है (और थंक का आकार मूल्य के आकार से संबंधित नहीं है)। सवाल यह है कि, एक डेटा प्रकार दिया जाता है, जब पूरी तरह से मूल्यांकन किया जाता है तो इसका मूल्य कितना मेमोरी है?

मैंने पाया कि :set +sमेमोरी के आँकड़े देखने के लिए GHCi में एक विकल्प है, लेकिन यह स्पष्ट नहीं है कि किसी एकल मान के मेमोरी फ़ुटप्रिंट का अनुमान कैसे लगाया जाए।

जवाबों:


156

(निम्नलिखित जीएचसी पर लागू होता है, अन्य संकलक विभिन्न भंडारण सम्मेलनों का उपयोग कर सकते हैं)

अंगूठे का नियम: एक कंस्ट्रक्टर एक हेडर के लिए एक शब्द और प्रत्येक क्षेत्र के लिए एक शब्द खर्च करता है । अपवाद: कोई भी फ़ील्ड (जैसे Nothingया True) वाला कोई निर्माता कोई स्थान नहीं लेता है, क्योंकि GHC इन निर्माणकर्ताओं का एक ही उदाहरण बनाता है और इसे सभी उपयोगों के बीच साझा करता है।

एक शब्द 32-बिट मशीन पर 4 बाइट्स और 64-बिट मशीन पर 8 बाइट्स है।

इसलिए उदा

data Uno = Uno a
data Due = Due a b

एक Unoलेता है 2 शब्द, और एक Dueलेता है 3।

Intप्रकार के रूप में परिभाषित किया गया है

data Int = I# Int#

अब, Int#एक शब्द लेता है, इसलिए Intकुल 2 लेता है। अधिकांश अनबॉक्स्ड प्रकार एक शब्द ले, अपवाद हैं Int64#, Word64#और Double#(32-बिट मशीन पर), जो ले 2. GHC वास्तव में प्रकार के छोटे मूल्यों की एक कैश है Intऔर Char, इसलिए कई मामलों में इन सब पर कोई ढेर अंतरिक्ष ले। एक Stringही है, सूची की कोशिकाओं के लिए स्थान की आवश्यकता होती है जब तक आप का उपयोग Char> रों 255।

एक Int8समान प्रतिनिधित्व है IntIntegerइस तरह परिभाषित किया गया है:

data Integer
  = S# Int#                            -- small integers
  | J# Int# ByteArray#                 -- large integers

इतना छोटा Integer( S#) 2 शब्द लेता है, लेकिन एक बड़ा पूर्णांक इसके मूल्य के आधार पर एक चर राशि लेता है। A ByteArray#, सरणी के लिए 2 शब्द (हेडर + साइज) प्लस स्पेस लेता है।

ध्यान दें कि एक निर्माता के साथ परिभाषित newtypeमुफ्त हैnewtypeविशुद्ध रूप से एक संकलन-समय का विचार है, और यह कोई स्थान नहीं लेता है और रन समय पर कोई निर्देश नहीं खर्च करता है।

जीएचसी टिप्पणी में ढेर वस्तुओं के लेआउट में अधिक जानकारी ।


1
धन्यवाद, साइमन। यह वही है जो मैं जानना चाहता था।
sastanin

2
क्या हेडर दो शब्द नहीं हैं? टैग के लिए एक, और जीसी या मूल्यांकन के दौरान उपयोग के लिए अग्रेषण सूचक के लिए एक? तो क्या आपके कुल में एक शब्द नहीं जोड़ा जाएगा?
एडवर्ड KMETT

5
@ एडवर्ड: थ्रो को अप्रत्यक्ष रूप से लिखा जाता है (जो बाद में जीसी द्वारा हटा दिया जाता है), लेकिन वे केवल 2 शब्द हैं, और प्रत्येक हीप ऑब्जेक्ट को आकार में कम से कम दो 2 शब्द होने की गारंटी है। हेडर को चालू किए बिना किसी भी प्रोफाइलिंग या डिबगिंग सुविधाओं के बिना वास्तव में केवल एक शब्द है। जीएचसी में, अर्थात् अन्य कार्यान्वयन चीजों को अलग तरीके से कर सकते हैं।
नॉमिनोलो जूल

3
नोमिनोलो: हाँ, लेकिन क्लोजर से ।h: / * थंक में अद्यतन मान लेने के लिए एक पैडिंग शब्द है। ऐसा इसलिए है कि अपडेट पेलोड को अधिलेखित नहीं करता है, इसलिए हम प्रवेश और अद्यतन के दौरान थन को लॉक करने की आवश्यकता से बच सकते हैं। नोट: यह THUNK_STATIC पर लागू नहीं होता है, जिसमें कोई पेलोड नहीं है। नोट: हम केवल एसएमपी के बजाय इस पेडिंग शब्द को सभी तरह से छोड़ देते हैं, ताकि हमें एसएमपी के लिए अपने सभी पुस्तकालयों को फिर से इकट्ठा न करना पड़े। * / अप्रत्यक्ष के दौरान पेलोड अधिलेखित नहीं होता है। अप्रत्यक्ष को हेडर में एक अलग स्थान पर लिखा गया है।
एडवर्ड KMETT

6
हां, लेकिन ध्यान दें कि यह केवल थ्रक्स के लिए है । यह कंस्ट्रक्टरों पर लागू नहीं होता है। किसी भी तरह से एक थंक के आकार का अनुमान लगाना थोड़ा मुश्किल है - आपको मुफ्त चर गिनना होगा।
नॉमिनोलो जूल

4

Gh-datasize पैकेज एक GHC ऑब्जेक्ट के आकार की गणना करने के लिए पुनरावर्ती कार्य प्रदान करता है । तथापि...

आकार की गणना करने से पहले एक कचरा संग्रह किया जाता है, क्योंकि कचरा संग्रहकर्ता ढेर चलना मुश्किल बना देगा।

... तो यह अक्सर कॉल करने के लिए व्यावहारिक नहीं होगा!

यह भी देखें कि डेटा प्रकारों की जीएचसी की मेमोरी अभ्यावेदन कैसे पता करें? और मैं हास्केल में एक प्रकार का आकार कैसे निर्धारित कर सकता हूं?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.