2009-02-23 9 views
23

में कुशल स्ट्रिंग कार्यान्वयन मैं वर्तमान में हास्केल को पढ़ रहा हूं, और मैं सोच रहा हूं कि हास्केल में तारों के साथ काम करते समय सबसे अच्छा अभ्यास क्या होता है।हास्केल

हास्केल में डिफ़ॉल्ट स्ट्रिंग कार्यान्वयन चार की एक सूची है। Real World Haskell के अनुसार, यह फ़ाइल इनपुट-आउटपुट के लिए अक्षम है, क्योंकि प्रत्येक चरित्र को अलग से आवंटित किया जाता है (मुझे लगता है कि इसका मतलब है कि एक स्ट्रिंग मूल रूप से हास्केल में एक लिंक्ड सूची है, लेकिन मुझे यकीन नहीं है।)

लेकिन अगर डिफ़ॉल्ट स्ट्रिंग कार्यान्वयन फ़ाइल I/o के लिए अक्षम है, क्या यह स्मृति में स्ट्रिंग्स के साथ काम करने के लिए भी अक्षम है? क्यों या क्यों नहीं? सी स्ट्रिंग का प्रतिनिधित्व करने के लिए चार की एक सरणी का उपयोग करता है, और मुझे लगता है कि यह ज्यादातर भाषाओं में चीजों को करने का डिफ़ॉल्ट तरीका होगा।

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

+0

डिफ़ॉल्ट कार्यान्वयन, छोटे तारों और सामान्य परिचालनों के लिए काम करने के लिए सबसे सुविधाजनक है, जो उन पर प्रदर्शन करना चाहता है। बड़े तारों के लिए जिन्हें आप मूल रूप से बाइट्स के ब्लॉक के रूप में मानना ​​चाहते हैं, यह कुशल नहीं है; Data.ByteString या Data.ByteString.Lazy – ShreevatsaR

उत्तर

30

हास्केल में तारों के साथ काम करने के लिए सर्वोत्तम अभ्यास मूल रूप से हैं: डेटा का उपयोग करें। डेटास्टिंग/डेटा। बाइटस्ट्रिंग.लाज़ी।

http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/


जहां तक ​​डिफ़ॉल्ट स्ट्रिंग कार्यान्वयन की दक्षता हास्केल में चला जाता है, यह नहीं है। प्रत्येक Char एक यूनिकोड कोडपॉइंट का प्रतिनिधित्व करता है जिसका अर्थ है कि इसे कम से कम 21 बिट प्रति Char की आवश्यकता है।

एक String के बाद से सिर्फ [Char] है, कि Char की एक लिंक्ड सूची है, इसका मतलब है String संदर्भ के गरीब इलाके है, और फिर इसका मतलब है कि String स्मृति पर्याप्त रूप से बड़ा, कम से कम यह N * (21bits + Mbits) है जहां N स्ट्रिंग की लंबाई और एम एक सूचक का आकार है (32, 64, आपके पास क्या है) और कई अन्य स्थानों के विपरीत जहां हास्केल सूचियों का उपयोग करता है जहां अन्य भाषाएं विभिन्न संरचनाओं का उपयोग कर सकती हैं (मैं विशेष रूप से यहां नियंत्रण प्रवाह का सोच रहा हूं), String संकलक द्वारा loops, आदि के लिए अनुकूलित करने में सक्षम होने की संभावना बहुत कम है।

और जब एक Char एक कोडपॉइंट से मेल खाती है, हास्केल 98 रिपोर्ट का उपयोग किया जब फ़ाइल कर आईओ, नहीं भी एक डिफ़ॉल्ट बहुत कम इसे बदलने के लिए एक तरह से एन्कोडिंग के बारे में कुछ भी निर्दिष्ट नहीं है। अभ्यास में जीएचसी ऐसा करने के लिए एक एक्सटेंशन प्रदान करता है उदा। बाइनरी आईओ, लेकिन आप वैसे भी उस बिंदु पर आरक्षण से बाहर जा रहे हैं।

स्ट्रिंग के सामने आगे बढ़ने जैसे संचालन के साथ भी यह संभावना नहीं है कि String अभ्यास में ByteString को हरा देगा।

+1

+1 का उपयोग करें, ठीक उसी पैकेज को मैं जवाब देने जा रहा था। बाइटस्ट्रिंग बाइट एरे में ऑफ़सेट के रूप में तारों को स्टोर करता है। Data.ByteString.Char8 आपको बाइट्सट्रिंग्स में सीधे चार्स का उपयोग करके यह मानकर कि केवल 8 बिट्स महत्वपूर्ण हैं (यानी ASCII)। बाइटस्ट्रिंग भी अपने स्वयं के कुशल आईओ कार्यों को प्रदान करता है। –

8

उत्तर "आलसी बाइटिंग्स" का उपयोग करने से थोड़ा अधिक जटिल है।

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

यह कहा गया कि, यदि आपको प्रदर्शन की आवश्यकता है और आप अपने डेटा को पूरी तरह से उपनिवेशों में प्रदर्शित कर सकते हैं, तो ऐसा करें।

33

स्ट्रिंग/बाइटस्ट्रिंग के अलावा अब Text लाइब्रेरी है जो दोनों दुनिया के सर्वश्रेष्ठ संयोजन को जोड़ती है- यह यूनिकोड के साथ काम करता है जबकि बाइटस्ट्रिंग-आधारित आंतरिक रूप से होता है, इसलिए आपको तेज, सही तार मिलते हैं।

+0

अच्छा; +1, धन्यवाद पोर्गस। –

6

दिए गए मूल उत्तर, बाइटस्ट्रिंग का उपयोग सही है। उस ने कहा, मेरे सामने तीनों उत्तरों में से सभी त्रुटियां हैं।

यूटीएफ -8 के संबंध में: चाहे यह कोई मुद्दा होगा या नहीं, पूरी तरह से निर्भर करता है कि आप अपने तारों के साथ किस तरह की प्रसंस्करण करते हैं। यदि आप उन्हें डेटा के एकल भाग के रूप में बस इलाज कर रहे हैं (जिसमें कॉन्सटेनेशन जैसे ऑपरेशंस शामिल हैं, हालांकि विभाजन नहीं हो रहे हैं), या कुछ सीमित बाइट-आधारित संचालन कर रहे हैं (उदाहरण के लिए, लंबाई में बजाए बाइट्स में स्ट्रिंग की लंबाई ढूंढना पात्र), आपको कोई समस्या नहीं होगी। यदि आप I18N का उपयोग कर रहे हैं, तो ByteString के बजाय String का उपयोग करने वाले पर्याप्त अन्य मुद्दे हैं जो आपको सामना करने वाली समस्याओं में से केवल कुछ ही ठीक करना शुरू कर देंगे।

बाइटस्ट्रिंग के सामने एक सिंगल बाइट तैयार करना शायद स्ट्रिंग के लिए ऐसा करने से अधिक महंगा है। हालांकि, यदि आप इनमें से बहुत कुछ कर रहे हैं, तो संभवतः आपकी विशेष समस्या से निपटने के तरीकों को ढूंढना संभव है जो सस्ता हैं।

लेकिन मूल परिणाम के पोस्टर के लिए अंतिम परिणाम होगा: हाँ, स्ट्रिंग्स हास्केल में अक्षम हैं, हालांकि यह आसान है। यदि आप दक्षता के बारे में चिंतित हैं, तो बाइटस्ट्रिंग्स का उपयोग करें, और उन्हें अपने उद्देश्य (ASCII/ISO-8859-1 बनाम यूनिकोड बनाम, या केवल मनमाना बाइनरी डेटा) के आधार पर Char8 या Word8 के सरणी के रूप में देखें। आम तौर पर, आलसी बाइटस्ट्रिंग्स का उपयोग करें (जहां एक स्ट्रिंग की शुरुआत में तैयारी करना वास्तव में एक बहुत तेज़ ऑपरेशन होता है) जब तक कि आप नहीं जानते कि आप गैर आलसी क्यों चाहते हैं (जिसे आम तौर पर आलसी मूल्यांकन के प्रदर्शन पहलुओं की सराहना में लपेटा जाता है)।

इसके लायक होने के लिए, मैं पूरी तरह से हास्केल में एक स्वचालित ट्रेडिंग सिस्टम का निर्माण कर रहा हूं, और उन चीजों में से एक जो हमें नेटवर्क कनेक्शन पर प्राप्त होने वाली बाज़ार डेटा फीड को बहुत तेज़ी से पार्स करना है। मैं सीपीयू की एक लापरवाही राशि के साथ प्रति सेकंड 300 संदेश पढ़ने और पार्सिंग को संभाल सकता हूं; जहां तक ​​इस डेटा को संभालने के लिए, जीएचसी-संकलित हास्केल सी के करीब पर्याप्त प्रदर्शन करता है कि यह उल्लेखनीय मुद्दों की मेरी सूची में प्रवेश करने के करीब कहीं नहीं है।