2012-06-26 11 views
6

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

प्रत्येक क्वेरी एक Tuple3 [स्ट्रिंग, Int, java.sql.Timestamp] लौट रही है। मुझे पता है कि स्ट्रिंग लगभग 20 वर्णों, यूटीएफ 8 से अधिक नहीं है।

मैं इन tuples में से किसी एक के अधिकतम आकार को कैसे काम कर सकता हूं, और अधिक आम तौर पर, मैं इस प्रकार एक स्कैला डेटा-संरचना के आकार का अनुमान कैसे लगा सकता हूं?

मुझे जिस मशीन का उपयोग मैं कर रहा हूं उस पर 6 जीबी है। हालांकि, स्कैला-लिस्ट में स्काला-क्वेरी का उपयोग करके डेटाबेस से डेटा पढ़ा जा रहा है।

उत्तर

6

स्कैला ऑब्जेक्ट्स जावा ऑब्जेक्ट्स के समान नियमों का पालन करते हैं, इसलिए उन पर कोई भी जानकारी सटीक है। Here is one source, जो कम से कम 32 बिट JVMs के लिए सही लगता है। (64 बिट जेवीएम 8 बाइट प्रति पॉइंटर का उपयोग करते हैं, जो आम तौर पर 4 बाइट अतिरिक्त ओवरहेड प्लस 4 बाइट्स प्रति पॉइंटर तक काम करता है - लेकिन यदि JVM संपीड़ित पॉइंटर्स का उपयोग कर रहा है, तो यह कम हो सकता है, जो अब डिफ़ॉल्ट रूप से करता है, मुझे लगता है।)

मैं संपीड़ित पॉइंटर्स (सबसे खराब मामला) के बिना 64 बिट मशीन मानूंगा; फिर Tuple3 में दो पॉइंटर्स (16 बाइट्स) प्लस Int (4 बाइट्स) प्लस ऑब्जेक्ट ओवरहेड (~ 12 बाइट्स) निकटतम 8, या 32 बाइट्स के साथ गोलाकार है, साथ ही एक अतिरिक्त ऑब्जेक्ट (8 बाइट्स) गैर- Int का विशेष संस्करण। (अफसोस की बात है, यदि आप ट्यूपल्स में प्राइमेटिव का उपयोग करते हैं तो वे लपेटने वाले संस्करणों का उपयोग करते समय और स्थान लेते हैं।)। String 32 बाइट्स, आईआईआरसी, साथ ही डेटा के लिए सरणी है जो प्रति चरित्र 16 प्लस 2 है। java.sql.Timestamp को Long एस (मुझे लगता है कि यह है) को स्टोर करने की आवश्यकता है, इसलिए यह 32 बाइट्स है। सभी ने कहा, यह 120 बाइट्स प्लस दो प्रति चरित्र के क्रम में है, जो ~ 20 वर्ण ~ 160 बाइट्स पर है।

वैकल्पिक रूप से, this answer देखें सीधे अपनी वस्तुओं के आकार को मापने के लिए। जब मैं इसे इस तरह मापता हूं, मुझे 160 बाइट मिलते हैं (और ऊपर दिए गए मेरे अनुमान को इस डेटा का उपयोग करके सही किया गया है, इसलिए यह मेल खाता है; मुझे पहले कई छोटी त्रुटियां थीं)।

+0

अच्छा बिंदु, मैं स्ट्रिंग प्लस ऑब्जेक्ट ओवरहेड में अतिरिक्त ओवरहेड के बारे में भूल गया। फिर भी, यह बहुत अधिक डेटा नहीं है। –

+0

स्ट्रिंग सरणी पर 24 प्लस 2 प्रति वर्ण क्यों? आईआईआरसी, एक ऐरे एक गैर-सरणी के साथ 8 बाइट बनाम 4 बाइट्स, साथ ही तत्व भी है। –

+0

@DanielC।सोब्राल - ऑब्जेक्ट ओवरहेड प्लस लम्बाई है, जो 64 बिट मशीन पर 16 बाइट्स है, इसलिए मैं थोड़ी देर से बंद था। –

2

आपके निपटारे में आपको कितनी मेमोरी मिली है? एक तिहाई के 6 मिलियन उदाहरण वास्तव में बहुत ज्यादा नहीं है!

प्रत्येक संदर्भ में एक ओवरहेड होता है जो या तो 4 या 8 बाइट्स होता है, इस पर निर्भर करता है कि आप 32- या 64-बिट (संपीड़ित "ओप्स" के बिना चल रहे हैं, हालांकि यह 32 जीबी के तहत ढेर के लिए जेडीके 7 में डिफ़ॉल्ट है)।

तो आपके ट्रिपल में 3 संदर्भ हैं (विशेषज्ञता के कारण अतिरिक्त हो सकते हैं - इसलिए आपको 4 रेफरी मिल सकती हैं), Timestamplong (8 बाइट्स) के आसपास एक रैपर (संदर्भ) है। आपका Int विशिष्ट होगा (यानी अंतर्निहित int), इसलिए यह एक और 4 बाइट बनाता है। स्ट्रिंग 20 x 2 बाइट्स है। तो आप मूल रूप से का सबसे खराब मामला प्रति पंक्ति 100 बाइट से कम है; तो प्रति पंक्ति 10 पंक्तियां, प्रति पंक्ति 10,000 पंक्तियां। तो आप 1 जीबी ढेर के नीचे अपनी 6 मिलियन पंक्तियों को आसानी से संसाधित कर सकते हैं।

सचमुच, मुझे लगता है कि मैंने यहां एक गलती की है क्योंकि हम इस जगह में लगभग बीस फ़ील्ड (दशमलव, स्ट्रिंग्स इत्यादि सहित) की कई मिलियन पंक्तियों को संसाधित करते हैं।

+0

इसके बारे में कोई हिंदकिचाहट? – matanster

संबंधित मुद्दे

 संबंधित मुद्दे