2014-05-09 6 views
6
p = re.compile('>.*\n') 
p.sub('', text) 

मैं '>' से शुरू होने वाली सभी लाइनों को हटाना चाहता हूं। मेरे पास वास्तव में एक विशाल फ़ाइल (3 जीबी) है जो मैं आकार 250 एमबी के टुकड़ों में संसाधित करता हूं, इसलिए चर "टेक्स्ट" आकार 250 एमबी की एक स्ट्रिंग है। (मैंने विभिन्न आकारों की कोशिश की, लेकिन प्रदर्शन पूरी फ़ाइल के लिए हमेशा एक ही था)।पायथन गति इस regex उप

अब, क्या मैं इस रेगेक्स को किसी भी तरह से तेज कर सकता हूं? मैंने बहु-रेखा मिलान करने की कोशिश की, लेकिन यह बहुत धीमी थी। या यहां तक ​​कि बेहतर तरीके भी हैं?

(मैंने स्ट्रिंग को विभाजित करने की कोशिश की है और फिर इस तरह की रेखा को फ़िल्टर किया है, लेकिन यह धीमा भी था (मैंने def delline के बजाय लैम्ब्डा की भी कोशिश की: (हो सकता है कि यह काम करने वाला कोड न हो, यह सिर्फ स्मृति से है) :

def del_line(x): return x[0] != '>' 

def func(): 
    .... 
    text = file.readlines(chunksize) 
    text = filter(del_line, text) 
    ... 

संपादित करें: के रूप में टिप्पणी में सुझाव दिया, मैं भी लाइन चलने लाइन द्वारा की कोशिश की:

text = [] 
for line in file: 
    if line[0] != '>': 
     text.append(line) 
text = ''.join(text) 

भी धीमी है यही कारण है, यह ~ की जरूरत है 12 सेकंड मेरे regex जरूरत ~ 7 सेकंड (।। हाँ, यह तेज़ है, लेकिन इसे धीमी मशीनों पर भी चलाना चाहिए)

संपादित करें: बेशक, मैं भी str.startswith ('>'), यह धीमी थी कोशिश की ...

+2

रेगेक्स –

+0

का उपयोग न करें '(? एम) ^> [^ \ n] * \ n', जंगली अनुमान का प्रयास करें। यकीन नहीं है कि यह कुछ भी सुधार होगा। – HamZa

+0

@ हम्ज़ा यह बहुत धीमा है। – Eulelie

उत्तर

0

यह तेजी से नहीं है?

def cleanup(chunk): 
    return '\n'.join(st for st in chunk.split('\n') if not(st and st[0] == '>')) 

संपादित करें: हाँ, यह तेज़ नहीं है। यह धीमा धीमा है।

शायद उपप्रचार और grep जैसे टूल का उपयोग करने पर विचार करें, जैसा कि रयान पी द्वारा सुझाया गया है। आप मल्टीप्रोसेसिंग का भी लाभ उठा सकते हैं।

+0

Thx! यह तेज़ नहीं है (मेरे रेगेक्स के साथ 10 सेकंड बनाम 7 सेकेंड)। मल्टीप्रोसेसिंग वैसे भी मेरा अगला कदम होगा, मैं बस पहले जांचना चाहता था, अगर मैं अभी भी चीजों को थोड़ा बढ़ा सकता हूं। – Eulelie

+0

हाँ, मैंने बस इसे समय दिया और यह आपके रेगेक्स से धीमा था। –

+0

मुझे नहीं लगता कि मल्टीप्रोसेसिंग यहां बहुत कुछ करेगी, क्योंकि समस्या मुख्य रूप से आईओ थ्रूपुट से संबंधित है। – jdehesa

1

यदि आपके पास मौका है, तो grep एक उपप्रोसेस के रूप में चल रहा है शायद सबसे व्यावहारिक विकल्प है।

यदि किसी भी कारण से आप grep पर भरोसा नहीं कर सकते हैं, तो आप कुछ "चाल" को लागू करने का प्रयास कर सकते हैं जो grep को तेज़ी से बनाते हैं। लेखक से स्वयं, आप यहां उनके बारे में पढ़ सकते हैं: http://lists.freebsd.org/pipermail/freebsd-current/2010-August/019310.html

लेख के अंत में, लेखक मुख्य बिंदुओं को सारांशित करता है। जो मुझे सबसे ज्यादा खड़ा करता है वह है:

इसके अलावा, जीएनयू grep लाइनों में इनपुट को स्वीकार करने से बचाता है। की तलाश में न्यूलाइन कई बार एक कारक द्वारा grep को धीमा कर देगी, क्योंकि को न्यूलाइन ढूंढने के लिए इसे प्रत्येक बाइट को देखना होगा!

विचार पूरी फ़ाइल को स्मृति में लोड करना होगा और लाइन-स्तर के बजाए बाइट-स्तर पर इसके साथ पुनरावृत्ति करना होगा। केवल जब आप एक मैच पाते हैं, तो आप लाइन सीमाओं की तलाश करते हैं और इसे हटा देते हैं।

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

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