2010-07-28 13 views
6

मैं कहीं से बाइट्स (ऐरे [बाइट]) की एक सरणी प्राप्त करना चाहता हूं (फ़ाइल से, सॉकेट, आदि से पढ़ें) और फिर बिट्स को खींचने के लिए एक प्रभावी तरीका प्रदान करें (उदाहरण के लिए 32- सरणी में ऑफ़सेट एन से बिट पूर्णांक)। मैं फिर बाइट सरणी (इसे छिपाने) को सरणी से बाहर खींचने के लिए कार्यों को प्रदान करना चाहता हूं (शायद प्रत्येक बिट के लिए आलसी मूल्य का उपयोग करके)।स्कैला में अपरिवर्तनीय बाइट सरणी करने का सबसे प्रभावी तरीका क्या है?

मैं कल्पना करता हूं कि एक रैपिंग क्लास है जो सरणी सामग्री को साबित करने के लिए कन्स्ट्रक्टर में एक अपरिवर्तनीय बाइट सरणी प्रकार लेता है, कभी संशोधित नहीं होता है। इंडेक्सडैक [बाइट] प्रासंगिक लग रहा था, लेकिन मैं काम नहीं कर सका [बाइट] से इंडेक्सडैक [बाइट] तक कैसे जाना है।

प्रश्न 2 का भाग 2 यह है कि अगर मैंने इंडेक्सडैक [बाइट] का उपयोग किया तो परिणामी कोड धीमा हो जाएगा? मुझे जितनी जल्दी हो सके निष्पादित करने के लिए कोड की आवश्यकता है, इसलिए अगर कंपाइलर इसके साथ बेहतर काम कर सकता है तो ऐरे [बाइट] के साथ चिपकेगा।

मैं सरणी के चारों ओर एक रैपर वर्ग लिख सकता हूं, लेकिन इससे चीजों को धीमा कर दिया जाएगा - सरणी में बाइट्स तक प्रत्येक पहुंच के लिए एक अतिरिक्त स्तर का संकेत। सरणी एक्सेस की संख्या के कारण प्रदर्शन महत्वपूर्ण है जो आवश्यक होगा। मुझे तेज़ कोड चाहिए, लेकिन एक ही समय में अच्छी तरह से कोड करना चाहते हैं। धन्यवाद!

पीएस: मैं एक स्कैला नौसिखिया हूं।

उत्तर

13

एक IndexedSeq[T] रूप Array[T] इलाज शायद ही सरल हो सकता है:

Array(1: Byte): IndexedSeq[Byte] // trigger an Implicit View 
wrapByteArray(Array(1: Byte)) // explicitly calling 

अनबॉक्सिंग अविवेक की अतिरिक्त परत से पहले लंबे समय तक तुम्हें मार देंगे।

C:\>scala -Xprint:erasure -e "{val a = Array(1: Byte); val b1: Byte = a(0); val 
b2 = (a: IndexedSeq[Byte])(0)}" 
[[syntax trees at end of erasure]]// Scala source: scalacmd5680604016099242427.s 
cala 

val a: Array[Byte] = scala.Array.apply((1: Byte), scala.this.Predef. 
wrapByteArray(Array[Byte]{})); 
val b1: Byte = a.apply(0); 
val b2: Byte = scala.Byte.unbox((scala.this.Predef.wrapByteArray(a): IndexedSeq).apply(0)); 

इससे बचने के लिए, स्काला संग्रह पुस्तकालय तत्व प्रकार पर, एक ही शैली में Tuple1 और Tuple2 के रूप में विशेष किया जाना चाहिए। मुझे बताया गया है कि यह योजनाबद्ध है, लेकिन यह हर जगह @specialized को बस मारने से थोड़ा अधिक जुड़ा हुआ है, इसलिए मुझे नहीं पता कि यह कितना समय लगेगा।

अद्यतन

हाँ, WrappedArray, परिवर्तनशील है, हालांकि collection.IndexedSeq[Byte], उत्परिवर्तित करने के लिए विधि नहीं है, इसलिए आप बस विश्वास ग्राहकों एक परिवर्तनशील इंटरफेस को कास्ट करने के लिए नहीं कर सका। स्कालाज़ की अगली रिलीज में ImmutableArray शामिल होगा जो इसे रोकता है।

मुक्केबाजी आता है इस सामान्य विधि के माध्यम से संग्रह से एक तत्व को पुन: प्राप्त:

trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => 
    def apply(idx: Int): A 
} 

JVM स्तर पर, यह हस्ताक्षर करने के लिए टाइप-मिटा दिया जाता है:

def apply(idx: Int): Object 

अपने संग्रह पुरातन शामिल हैं , यानी, AnyVal के उपप्रकार, उन्हें इस विधि से वापस आने के लिए संबंधित रैपर में बॉक्स किया जाना चाहिए। कुछ अनुप्रयोगों के लिए, यह एक प्रमुख प्रदर्शन चिंता है। इस पुस्तकालय से बचने के लिए संपूर्ण पुस्तकालयों को जावा में लिखा गया है, विशेष रूप से fastutils

Annotation directed specialization स्केल 2.8 में जोड़ा गया था ताकि संकलक को कक्षा के विभिन्न संस्करणों को उत्पन्न करने के लिए निर्देश दिया जा सके या प्राचीन प्रकार के क्रमपरिवर्तन के अनुरूप विधि बनाया जा सके। यह पहले से ही मानक पुस्तकालय में कुछ स्थानों पर लागू किया गया है, उदा। TupleN, ProductN, Function{0, 1, 2}।यदि यह संग्रह पदानुक्रम पर भी लागू किया गया था, तो इस प्रदर्शन लागत को कम किया जा सकता है।

अपरिवर्तनीय seqs:

(लिंक किए गए seqs) सूची, स्ट्रीम, कतार

(अनुक्रमित

+0

क्षमा करें, एक स्कैला नौसिखिया के रूप में मैं आपका उदाहरण समझ नहीं पा रहा हूं। क्या आप कह रहे हैं कि ऐरे [बाइट] का उपयोग करके बहुत सारे अनबॉक्सिंग होंगे? इसके अलावा मुझे यकीन नहीं था कि अंतर्निहित दृष्टिकोण को कैसे ट्रिगर किया जाए। मैंने स्पष्ट रूप से जोड़ा ": इंडेक्सडैक [बाइट]" मेरे सरणी अस्थिरता के बाद, लेकिन "टाइप मिस्चैच" के साथ शिकायत की गई। इसके अलावा, wrapByteArray() एक म्यूटेबल इंडेक्सडैक [बाइट] वापस करने लगता है, अपरिवर्तनीय संस्करण नहीं। –

11

आप स्काला में दृश्यों के साथ काम करना चाहते हैं, मैं आप इन में से एक चुनने की सलाह देते seqs) वेक्टर

परिवर्त्य seqs:

(लिंक किए गए seq) ListBuffer

(अनुक्रमित seq) ArrayBuffer

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

alt text http://www.programmera.net/scala/img/seq_tree.png

इसके अलावा, ध्यान दें कि Array वृक्ष संरचना का हिस्सा नहीं है, यह एक विशेष मामला है, क्योंकि यह जावा सरणी लपेटता (जो जावा में एक विशेष मामला है)।

+3

स्कैला 2.8 में, इसका 'ऐरे' जावा के सरणी के लिए है क्योंकि स्कैला की 'स्ट्रिंग' जावा की 'स्ट्रिंग' है: एक और वही, लपेटा नहीं गया है। ऐसे निहित रूपांतरणों वाले रैपर हैं जो इन "उधार" प्रकारों के साथ अनुक्रमों के लिए स्कैला के एचओएफ जैसी चीजों को उपयोग करने की अनुमति देते हैं, लेकिन मूल 'ऐरे' (और 'स्ट्रिंग') जावा इकाइयां हैं। –

+0

धन्यवाद - लेकिन दृष्टिकोण के प्रदर्शन पर कोई टिप्पणी? यही है, अगर मैं अपने कोड में इंडेक्सडैक [बाइट] का उपयोग करता हूं, तो क्या यह जावा में ऐरे [बाइट] (बाइट []) जितना तेज होगा? मुझे लगता है कि एक और प्रतिक्रिया अनबॉक्सिंग ओवरहेड्स के बारे में चेतावनी देती है - क्या वे बाइट्स के सरणी से निपटने के लिए स्कैला प्रदर्शन को मारने जा रहे हैं? –

+1

'वेक्टर' (स्केल 2.8.0 में विभिन्न 'रेंज' कक्षाओं और 'लपेटा हुआ स्ट्रिंग' के अलावा 'इंडेक्सेडस्क' का एकमात्र तत्काल उप-वर्ग) स्केल 2.8.0 में विशिष्ट नहीं है (किसी भी तत्व प्रकार के लिए), तो आप एक उच्च स्मृति का भुगतान करने जा रहे हैं जैसा कि आप कहते हैं, मुक्केबाजी और अनबॉक्सिंग के कारण ओवरहेड के साथ-साथ एक मामूली पहुंच समय लागत भी। –

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

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