2016-02-24 13 views
11

यहां एक अजीब व्यवहार है जिसमें मैं गिर गया और मुझे ऐसा कोई संकेत नहीं मिला कि यह ऐसा क्यों है। मैं इस उदाहरण estimate method of SizeEstimator from Spark में उपयोग, लेकिन मैं अपने कोड में कोई गड़बड़ नहीं मिला है तो मुझे आश्चर्य है कि क्यों - अगर वे स्मृति का एक अच्छा अनुमान प्रदान करते हैं - मैं ऐसा क्यों है:स्कैला - इस मामले में फ्लोट्स की तुलना में डबल क्यों कम स्मृति का उपभोग करते हैं?

val buf1 = new ArrayBuffer[(Int,Double)] 
var i = 0 
while (i < 3) { 
    buf1 += ((i,i.toDouble)) 
    i += 1 
} 
System.out.println(s"Raw size with doubles: ${SizeEstimator.estimate(buf1)}") 
val ite1 = buf1.toIterator 
var size1: Long = 0l 
while (ite1.hasNext) { 
    val cur = ite1.next() 
    size1 += SizeEstimator.estimate(cur) 
} 
System.out.println(s"Size with doubles: $size1") 

val buf2 = new ArrayBuffer[(Int,Float)] 
i = 0 
while (i < 3) { 
    buf2 += ((i,i.toFloat)) 
    i += 1 
} 
System.out.println(s"Raw size with floats: ${SizeEstimator.estimate(buf2)}") 
val ite2 = buf2.toIterator 
var size2: Long = 0l 
while (ite2.hasNext) { 
    val cur = ite2.next() 
    size2 += SizeEstimator.estimate(cur) 
} 
System.out.println(s"Size with floats: $size2") 

सांत्वना उत्पादन प्रिंट:

Raw size with doubles: 200 
Size with doubles: 96 
Raw size with floats: 272 
Size with floats: 168 

तो मेरा प्रश्न काफी बेवकूफ है: फ्लोट्स इस मामले में युगल से अधिक स्मृति क्यों लेते हैं? और जब मैं इसे एक पुनरावर्तक में बदलता हूं तो यह और भी बदतर क्यों होता है (पहला मामला, 75% अनुपात होता है जो एक पुनरावर्तक में परिवर्तित होने पर 50% अनुपात बन जाता है!)।

(अधिक संदर्भ के लिए, मैं इस में जब Float को Double बदलकर करने के लिए "का अनुकूलन" एक स्पार्क आवेदन की कोशिश कर गिर गया और पता चला कि यह वास्तव में युगल की तुलना में तैरता होने अधिक स्मृति ले लिया ...)

पी एस : यह बफ़र्स (यहाँ 3) के छोटे आकार की वजह से नहीं है, अगर मैं 100 डाल बजाय मैं:

Raw size with doubles: 3752 
Size with doubles: 3200 
Raw size with floats: 6152 
Size with floats: 5600 

और तैरता अभी भी और अधिक स्मृति का उपभोग ... लेकिन अनुपात स्थिर है, तो ऐसा लगता है कि इटेटरेटर में परिवर्तन में अलग-अलग अनुपात मुझे लगता है कि कुछ ओवरहेड के कारण होना चाहिए।

संपादित करें: ऐसा लगता है कि वास्तव में केवल Product2Int, Long और Double पर विशेष है:

trait Product2[@specialized(Int, Long, Double) +T1, @specialized(Int, Long, Double) +T2] extends Any with Product 

किसी को भी पता है क्यों Float ध्यान में नहीं रखा जाता है? न तो Short जो अजीब व्यवहार की ओर जाता है ...

+0

खेद मैं नहीं था int और आवरण प्रकार के साथ संरचना के रूप में प्रस्तुत किया जाएगा एवर पोस्ट करने से पहले अपडेट नहीं देखें। अगर आप चाहें, तो मैं – Odomontois

+0

उत्तर को हटा सकता हूं, आपका कोई जवाब अच्छा नहीं है क्योंकि आपने एक लिंक प्रदान किया है जो समझाया गया है कि यह सभी प्राइमेटिव्स पर क्यों विशिष्ट नहीं है! यह संयोजन संख्या के कारण है जो इसका नेतृत्व करेगा ... जो वास्तव में समझ में आता है =) यह जानना अच्छा है कि मैंने कोशिश की तरह बेवकूफ अनुकूलित करने की कोशिश करने से पहले! –

उत्तर

13

इसका कारण यह है Tuple2Double के लिए @specialized है, लेकिन Float के लिए विशेष नहीं है।

इसका मतलब है कि (Int,Double), आदिम जावा प्रकार int और double के 2 क्षेत्रों के साथ संरचना के रूप में प्रस्तुत किया जाएगा, जबकि (Int,Float)java.lang.Float क्षेत्रों

अधिक चर्चा here

+0

आपके लिंक में कुछ अजीब बात है, वे इसे बताते हैं क्योंकि वे बहुत अधिक विशेषज्ञता नहीं चाहते हैं। लेकिन जब आप कोड को देखते हैं, तो उत्पाद 3 भी विशिष्ट नहीं है ... तो यह केवल उत्पाद 1 और प्रॉडकट 2 है ... वे आसानी से फ्लोट्स और शॉर्ट्स के रूप में सामान्य प्रकारों पर कुछ विशेषज्ञता जोड़ सकते हैं! –

+1

@ विन्स.बीडीएन 'टुपले 2' का इस्तेमाल अक्सर 'टुपले 3' से किया जाता है। तो मुझे लगता है कि उन्होंने निर्णय लिया कि लाइब्रेरी जार आकार के लायक नहीं है। कुशल जेनेरिक परिवर्तनों के लिए आप प्रभावी स्टोर के लिए केस क्लास का उपयोग कर सकते हैं, [मिनीबॉक्सिंग] (http://scala-miniboxing.org) कुशल पहुंच के लिए और [आकारहीन] (https://github.com/milessabin/shapeless) – Odomontois

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

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