किसी सूची के विपरीत F # में अनुक्रम का उपयोग कब करें?


82

मैं समझता हूं कि एक सूची में वास्तव में मूल्य शामिल हैं, और एक अनुक्रम के लिए एक उपनाम है IEnumerable<T>। व्यावहारिक F # विकास में, मुझे किसी सूची के विपरीत अनुक्रम का उपयोग कब करना चाहिए?

यहां कुछ कारण दिए गए हैं जो मैं देख सकता हूं कि जब कोई क्रम बेहतर होगा:

  • अन्य .NET भाषाओं या पुस्तकालयों के साथ बातचीत करते समय जिनकी आवश्यकता होती है IEnumerable<T>
  • एक अनंत अनुक्रम का प्रतिनिधित्व करने की आवश्यकता है (शायद वास्तव में व्यवहार में उपयोगी नहीं है)।
  • आलसी मूल्यांकन की आवश्यकता है।

क्या कोई और हैं?


3
मुझे अनंत सीक्वेंस बहुत उपयोगी और सामान्य लगते हैं। System.Random.Next () पहले से ही भेस में एक "अनंत अनुक्रम" है, उदाहरण के लिए। अक्सर मैं कुछ ऐसा चाहता हूं जो आवश्यकतानुसार कई तत्वों को उत्पन्न करता है। मैंने हाल ही में एफ # में एक टेट्रिस लिखा और एक अनंत अनुक्रम के रूप में ब्लॉक पीढ़ी का प्रतिनिधित्व किया: यह उतना ही पैदा करेगा जितना कि खेल चलता है।
असिक

2
@Dr_Asik ध्यान दें कि हर बार जब आप इसे देखते हैं तो एक seqउत्पन्न होने वाला तरीका अलग-अलग यादृच्छिक संख्याएं पैदा करेगा । यह स्पष्ट रूप से गैर-नियतात्मक बगों का एक स्रोत हो सकता है ...
जेडी

जवाबों:


96

मुझे लगता है कि चुनने के लिए आपका सारांश Seqबहुत अच्छा है। यहाँ कुछ अतिरिक्त बिंदु हैं:

  • Seqफ़ंक्शन लिखते समय डिफ़ॉल्ट रूप से उपयोग करें , क्योंकि तब वे किसी भी .NET संग्रह के साथ काम करते हैं
  • Seqयदि आपको उन्नत कार्यों की आवश्यकता है, तो इसका उपयोग करें Seq.windowedयाSeq.pairwise

मुझे लगता है कि Seqडिफ़ॉल्ट रूप से चुनना सबसे अच्छा विकल्प है, इसलिए मैं विभिन्न प्रकार कब चुनूंगा?

  • पैटर्न Listका उपयोग करते समय आपको पुनरावर्ती प्रसंस्करण की आवश्यकता होती है (मानक पुस्तकालय में उपलब्ध कुछ कार्यक्षमता को लागू करने के लिए) का उपयोग करेंhead::tail

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

  • का प्रयोग करें Listजब आप कम सूचियों के साथ काम - सूची उपयोग करने के लिए सबसे अच्छा डेटा संरचना है अगर मूल्य अक्सर एक का प्रतिनिधित्व करता है खाली सूची है, क्योंकि यह उस स्थिति में बहुत ही कुशल है

  • का प्रयोग करें Arrayजब आप मूल्य प्रकार के बड़े संग्रह की जरूरत है
    (सरणियों, एक फ्लैट स्मृति ब्लॉक में डेटा स्टोर ताकि वे इस मामले में कुशल अधिक स्मृति कर रहे हैं)

  • Arrayरैंडम एक्सेस या अधिक प्रदर्शन (और कैश लोकेलिटी) की आवश्यकता होने पर उपयोग करें


1
महान धन्यवाद - वास्तव में मैं उसके बाद क्या था। F # सीखते समय इसकी उलझन यह है कि ये दो तत्व (सूची और seq) क्यों हैं, जो आपको समान कार्यक्षमता देते हैं।
dodgy_coder

3
"उपयोग करें List... ...] जब आपको एक सरल अपरिवर्तनीय डेटा संरचना की आवश्यकता होती है जिसे आप चरण-दर-चरण बना सकते हैं [...] और समवर्ती रूप से सूची को दूसरे धागे पर बनाना जारी रखते हैं [...]" क्या आप अपने बारे में विस्तार से बता सकते हैं यहाँ अर्थ / यह कैसे काम करता है? धन्यवाद।
Narfanar

2
@ नोइन यह विचार है कि आप हमेशा सूचियों पर पुनरावृति कर सकते हैं (वे अपरिवर्तनीय हैं) लेकिन आप x::xsकिसी भी मौजूदा श्रमिकों को तोड़ने के बिना नई सूचियों का निर्माण कर सकते हैं, जो इससे अधिक होने की प्रक्रिया में हो सकते हैंxs
टॉमस पेट्रीसेक

29

इसके अलावा पसंद करें seqजब:

  • आप एक ही समय में सभी तत्वों को स्मृति में नहीं रखना चाहते हैं।

  • प्रदर्शन महत्वपूर्ण नहीं है।

  • गणना से पहले और बाद में आपको कुछ करने की जरूरत है, जैसे एक डेटाबेस से कनेक्ट करें और कनेक्शन बंद करें।

  • आप समवर्ती नहीं हैं (बार-बार Seq.appendओवरफ्लो हो जाएगा)।

पसंद करें listजब:

  • कुछ तत्व हैं।

  • आप बहुत कम कर रहे हैं

न तो समानता के लिए अच्छे हैं seqऔर न ही listइसका मतलब यह नहीं है कि वे बुरे हैं। उदाहरण के लिए, आप समानांतर में किए जाने वाले अलग-अलग काम की वस्तुओं के एक छोटे समूह का प्रतिनिधित्व करने के लिए उपयोग कर सकते हैं।


"न तो seq और न ही सूची समानता के लिए अच्छे हैं": क्या आप इस बात का विस्तार कर सकते हैं कि seq समानता के लिए अच्छा क्यों नहीं है? समानांतरवाद के लिए क्या अच्छा है, केवल सरणी?
असिक

5
@Dr_Asik Arrays सर्वश्रेष्ठ हैं क्योंकि आप उन्हें पुन: प्रस्तुत कर सकते हैं और संदर्भ की अच्छी स्थानीयता बनाए रख सकते हैं। पेड़ अगले सबसे अच्छे हैं क्योंकि आप उन्हें भी वश में कर सकते हैं लेकिन संदर्भ की स्थानीयता इतनी अच्छी नहीं है। सूची और क्रम खराब हैं क्योंकि आप उन्हें तोड़ नहीं सकते। यदि आप वैकल्पिक तत्वों की खेती करते हैं, तो आपको संदर्भ का सबसे खराब संभव स्थान मिलता है। गाइ स्टील ने रेखीय संग्रहों की समानता पर चर्चा करते हुए चर्चा की है, हालांकि वे केवल काम और गहराई को मानते हैं और स्थानीयता (उर्फ कैश जटिलता ) को नहीं। labs.oracle.com/projects/plrg/Publications/…
JD

12

सिर्फ एक छोटा बिंदु: Seqऔर समानता के लिए Arrayबेहतर हैं List

आपके पास कई विकल्प हैं: पी # एफ से पावरपैक , अर्रे.पैरल्ट मॉड्यूल और एसिंक्स्पसमानांतर (अतुल्यकालिक गणना)। इसकी अनुक्रमिक प्रकृति ( head::tailरचना) के कारण समानांतर निष्पादन के लिए सूची भयानक है ।


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

1
आप यह क्यों कहते हैं कि seqसमानतावाद से बेहतर है list? seqउनके अनुक्रमिक स्वभाव के कारण समानांतर निष्पादन के लिए भी भयानक हैं ...
JD

7

सूची अधिक कार्यात्मक, गणित के अनुकूल है। जब प्रत्येक तत्व समान होता है, तो 2 सूचियां समान होती हैं।

अनुक्रम नहीं है।

let list1 =  [1..3]
let list2 =  [1..3]
printfn "equal lists? %b" (list1=list2)

let seq1 = seq {1..3}
let seq2 = seq {1..3}
printfn "equal seqs? %b" (seq1=seq2)

यहाँ छवि विवरण दर्ज करें


5

आपको हमेशा Seqअपने सार्वजनिक एपीआई में उजागर करना चाहिए । का प्रयोग करें Listऔर Arrayअपने आंतरिक कार्यान्वयन में।


क्या इसलिए कि वे अन्य .NET भाषाओं के साथ अच्छी तरह से काम करते हैं? क्योंकि एक के Seqरूप में देखा जाता है IEnumerable<T>?
dodgy_coder

अच्छा डिजाइन प्रथाओं के कारण यह नहीं। जितना जरूरी हो, उतनी जानकारी उजागर करें।
एलेक रौबिके

ओके निष्पक्ष टिप्पणी, यह सी # कोड के लिए अच्छा अभ्यास है - यानी एक फ़ंक्शन को उदाहरण के लिए भारी सूची <टी> के बजाय IEnumerable <T> के रूप में परिभाषित किया जा सकता है।
dodgy_coder

1
मैं परस्पर रिटर्न संरचनाओं के संदर्भों में सहमत हूं (जैसे .NET में यह डिज़ाइन दोष: msdn.microsoft.com/en-us/library/afadtey7.aspx ) या अन्य .NET भाषाओं से उपयोग किए जा सकने वाले API लेकिन मैं नहीं सामान्य रूप से सहमत, आंशिक रूप से क्योंकि seqसमानता के लिए बहुत बुरे हैं।
जद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.