2016-07-30 10 views
6

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

code on the haskell wiki से प्रेरित होकर, मैं निम्नलिखित अनुभवहीन प्रयास के साथ आया था:

{-# LANGUAGE FlexibleContexts, ExistentialQuantification #-} 

import Text.Regex.PCRE 
import System.Environment 

io :: ([String] -> [String]) -> IO() 
io f = interact (unlines . f . lines) 

regexBool :: forall r l . 
    (RegexMaker Regex CompOption ExecOption r, 
    RegexLike Regex l) => 
    r -> l -> Bool 
regexBool r l = l =~ r :: Bool 

grep :: forall r l . 
    (RegexMaker Regex CompOption ExecOption r, RegexLike Regex l) => 
    r -> [l] -> [l] 
grep r = filter (regexBool r) 

main :: IO() 
main = do 
    argv <- getArgs 
    io $ grep $ argv !! 0 

यह कर रही है कि क्या मैं इसे करना चाहते हैं प्रकट होता है, लेकिन दुर्भाग्य से, यह वास्तव में धीमी है - के बारे में 10 बार की तुलना में धीमी एक पाइथन लिपि एक ही काम कर रही है। मुझे लगता है कि यह रेगेक्स लाइब्रेरी नहीं है जो यहां गलती है, क्योंकि यह पीसीआरई में कॉल कर रहा है जो बहुत तेज होना चाहिए (Text.Regex.Posix पर स्विचिंग कुछ और चीजों को धीमा कर देता है)। तो यह String कार्यान्वयन होना चाहिए, जो सैद्धांतिक दृष्टिकोण से निर्देशक है लेकिन जो मैंने पढ़ा है उसके अनुसार अक्षम है।

दोनों कुशल और सुविधाजनक है कि हास्केल में String रों के लिए एक विकल्प है (यानी वहाँ कम या कोई घर्षण का उपयोग करते समय कि बजाय String रों का उपयोग करने जा) और कहा कि पूरी तरह से और सही ढंग से, संभालती है UTF-8 एन्कोड यूनिकोड के साथ-साथ यदि संभव हो तो बिना किसी परेशानी के अन्य एन्कोडिंग के रूप में? कुछ ऐसा है जो हर कोई हैकेल में पाठ प्रसंस्करण करते समय उपयोग करता है लेकिन मुझे बस इतना पता नहीं है क्योंकि मैं एक पूर्ण शुरुआत कर रहा हूं?

+7

[टेक्स्ट] का उपयोग करें (https://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html) – ErikR

+2

बस यह इंगित करना चाहता था कि सी-जैसी गति संभव है, लेकिन यह कुछ प्रयास कर सकता है। __cgrep__ पर एक नज़र डालें - http://awgn.github.io/cgrep/ – ErikR

+4

'स्ट्रिंग' एक कम-प्रदर्शन, आलसी स्ट्रिंग है, जो मूल लघु तारों के लिए" ठीक "है लेकिन गंभीर टेक्स्ट मैनिपुलेशन के लिए अनुपयुक्त है। यूनिकोड टेक्स्ट मैनिपुलेशन के लिए 'टेक्स्ट' उच्च-प्रदर्शन प्रकार है। (वहां 'बाइटस्ट्रिंग' भी है जो पाठ के लिए _not_ है लेकिन बाइट अनुक्रमों के लिए है।) – chi

उत्तर

1

यह संभव है कि धीमी गति मानक पुस्तकालय की सूची प्रकार का उपयोग करके हो। मैंने अक्सर अतीत में प्रदर्शन समस्याओं में भाग लिया है।

अपने निष्पादन योग्य को प्रोफ़ाइल करना एक अच्छा विचार होगा, यह देखने के लिए कि यह कहां व्यतीत करता है: Tools for analyzing performance of a Haskell program। प्रोफाइलिंग हास्केल प्रोग्राम वास्तव में आसान है (एक स्विच के साथ संकलित करें और अपने प्रोग्राम को एक अतिरिक्त तर्क के साथ निष्पादित करें, और रिपोर्ट वर्तमान कार्यशील निर्देशिका में एक टेक्स्ट फ़ाइल में लिखी गई है)।

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

+0

पर टिप के लिए धन्यवाद देना चाहिए , मुझे नहीं पता था कि हैकेल के पास बॉक्स से इतना अच्छा प्रोफाइलिंग समर्थन था! ऐसा लगता है कि मैं 'io' में लगभग दो तिहाई और' regexBool' (ऊपर देखें) में एक तिहाई खर्च कर रहा हूं, इसलिए यहां कोई वास्तविक आश्चर्य नहीं है - मुझे बस उन कॉलों को तेज़ी से बनाने की ज़रूरत है ... उपरोक्त अन्य टिप्पणीकारों द्वारा बताए गए 'स्ट्रिंग' के बजाय 'टेक्स्ट' का उपयोग करके करने योग्य द्वारा किया जाना चाहिए; केवल परेशानी है, मैं अपना प्रोग्राम नहीं प्राप्त कर पा रहा हूं अब तक इस संशोधन के साथ टाइप चेक। – dlukes

+0

@dlukes - इस बात पर निर्भर करता है कि आप किस रेगेक्स-लाइब्रेरी का उपयोग कर रहे हैं - मुझे लगता है कि रेगेक्स-हेवी में 'टेक्स्ट' का समर्थन है, दूसरों को केवल 'स्ट्रिंग'/'बाइटस्ट्रिंग' लगता है, लेकिन शायद इनलाइनों के साथ आपकी आवश्यकताओं के लिए पर्याप्त है। – epsilonhalbe