performance - स्केल की मानक लाइब्रेरी में @specialized कुछ चीजें क्यों हैं?




scala collections autoboxing specialized-annotation (4)

मैंने Scala 2.8.1 के मानक पुस्तकालय के स्रोत कोड में @specialized के उपयोग के लिए खोज की है। ऐसा लगता है कि केवल कुछ ही लक्षण और वर्ग इस एनोटेशन का उपयोग करते हैं: Function0 , Function1 , Function2 , Tuple1 , Tuple2 , Product1 , Product2 , AbstractFunction0 , AbstractFunction1 , AbstractFunction2

कोई भी संग्रह वर्ग @specialized । क्यों नहीं? क्या यह बहुत सारी कक्षाएं उत्पन्न करेगा?

इसका मतलब यह है कि आदिम प्रकार के साथ संग्रह कक्षाओं का उपयोग करना बहुत ही अक्षम है, क्योंकि इसमें बहुत सारी अनावश्यक मुक्केबाजी और अनबॉक्सिंग चल रही होगी।

बॉक्सिंग और IndexedSeq से बचने के लिए, IndexedSeq सूची या अनुक्रम ( IndexedSeq विशेषताओं के साथ) का सबसे कुशल तरीका क्या है?


Answers

कक्षाओं के आकार पर विशेषज्ञता की उच्च लागत है, इसलिए इसे सावधानी से जोड़ा जाना चाहिए। संग्रह के विशेष मामले में, मुझे लगता है कि प्रभाव बहुत बड़ा होगा।

फिर भी, यह एक ऑन-गोइंग प्रयास है - स्काला लाइब्रेरी को विशेष रूप से शुरू किया गया है।


विशिष्ट आकार वर्गों और संकलन समय दोनों में महंगा ( घातीय ) हो सकता है। इसका आकार स्वीकार्य उत्तर की तरह नहीं है।

अपना scala REPL खोलें और इसे टाइप करें।

import scala.{specialized => sp}
trait S1[@sp A, @sp B, @sp C, @sp D] { def f(p1:A): Unit }

माफ़ कीजिये :-)। यह एक कंपाइलर बम की तरह है।

अब, एक सरल लक्षण लेने देता है

trait Foo[Int]{ }

उपरोक्त दो संकलित वर्गों में परिणाम देगा। फू, शुद्ध इंटरफ़ेस और फू $ 1, वर्ग कार्यान्वयन।

अभी व,

trait Foo[@specialized A] { }

यहां एक विशेष टेम्प्लेट पैरामीटर 9 अलग-अलग आदिम प्रकारों (शून्य, बूलियन, बाइट, चार, इंट, लॉन्ग, शॉर्ट, डबल, फ्लोट) के लिए विस्तारित / फिर से लिखा जाता है। तो, मूल रूप से आप 2 के बजाय 20 वर्गों के साथ समाप्त होते हैं।

5 विशेष टेम्प्लेट मापदंडों के साथ विशेषता पर वापस जा रहे हैं, कक्षाएं संभव आदिम प्रकारों के हर संयोजन के लिए उत्पन्न होती हैं। यानी जटिलता में इसका घातांक।

2 * 10 ^ (कोई विशेष पैरामीटर नहीं)

यदि आप एक विशिष्ट आदिम प्रकार के लिए एक वर्ग को परिभाषित कर रहे हैं, तो आपको इसके बारे में अधिक स्पष्ट होना चाहिए जैसे कि

trait Foo[@specialized(Int) A, @specialized(Int,Double) B] { }

सामान्य प्रयोजन पुस्तकालयों का निर्माण करते समय विशेष रूप से उपयोग करके मितव्ययी होना पड़ता है।

Here पॉल फिलिप्स इसके बारे में शेख़ी कर रहा है।


मेरे अपने प्रश्न का आंशिक उत्तर: मैं इस तरह एक IndexedSeq में एक सरणी लपेट सकता हूं:

import scala.collection.immutable.IndexedSeq

def arrayToIndexedSeq[@specialized(Int) T](array: Array[T]): IndexedSeq[T] = new IndexedSeq[T] {
  def apply(idx: Int): T = array(idx)
  def length: Int = array.length
}

(अगर आप अंतर्निहित सरणी तक पहुँच प्राप्त करते हैं, तो आप अभी भी सामग्री को संशोधित कर सकते हैं, लेकिन मैं यह सुनिश्चित करूँगा कि सरणी मेरे कार्यक्रम के अन्य भागों में पारित नहीं हुई है)।


मौजूदा जेवीएम स्कैला के साथ स्थिर रूप से टाइप होने के कारण एक फायदा है, क्योंकि गतिशील टाइपिंग के लिए जेवीएम समर्थन - प्रतिबिंब - धीमा है। वास्तव में, एक स्कैला सुविधा जिसे एक ही तकनीक, संरचनात्मक प्रकारों के माध्यम से कार्यान्वित किया जाना चाहिए, अक्सर इस कारण से चेतावनी दी जाती है।

इसके अलावा, स्कैला म्यूटेबल ऑब्जेक्ट्स को ठीक से स्वीकार करता है, और कुछ एल्गोरिदम म्यूटेबिलिटी के साथ लागू करने के लिए बस तेज़ होते हैं।

चूंकि स्कैला और जावा दोनों अनिवार्य रूप से कक्षा-आधारित भाषाएं हैं, इसलिए वे अधिक आसानी से इंटरऑपरेट करते हैं। या, शायद, अधिक सहजता से। जावा क्लास स्कैला के लिए एक कक्षा है, और एक स्कैला क्लास जावा के लिए एक कक्षा है। जब स्कैला के सिंगलेट या जावा के स्थिर सदस्यों की बात आती है तो समस्याएं उत्पन्न हो सकती हैं, खासकर जब एक ढांचा होता है जिसमें चीजों को एक निश्चित तरीके से काम करने की अपेक्षा की जाती है।

तो मैं इन दोनों खातों पर स्कैला के साथ जाऊंगा। क्लोजर, कई तरीकों से, एक बेहतर भाषा है , और इसमें निश्चित रूप से बहुत ही रोचक विशेषताएं हैं जो स्कैला पर मौजूद नहीं हैं (लेकिन अब तक), लेकिन आप पूरी तरह कार्यात्मक जाकर ऐसे लाभ प्राप्त करते हैं। यदि आप ऐसा करने का इरादा रखते हैं, तो क्लोजर बहुत बेहतर है। यदि आप नहीं करते हैं, तो आपको शायद स्कैला के साथ रहना चाहिए।







performance scala collections autoboxing specialized-annotation