2010-08-15 14 views
5

मेरे पास एक स्क्रिप्ट है कि, जब टाइमर के खिलाफ रखा जाता है, तो धीरे-धीरे धीमा हो जाता है। यह काफी सरल है क्योंकि यह सब एक पंक्ति पढ़ता है, इसे जांचता है और फिर इसे डेटाबेस में जोड़ता है, फिर अगली पंक्ति में आता है।PHP स्क्रिप्ट प्रगतिशील धीमी हो जाती है (फ़ाइल रीडर)

Record: #1,001 Memory: 1,355,360kb taking 1.84s 
Record: #1,001 Memory: 1,355,360kb taking 1.84s 
Record: #2,002 Memory: 1,355,192kb taking 2.12s 
Record: #3,003 Memory: 1,355,192kb taking 2.39s 
Record: #4,004 Memory: 1,355,192kb taking 2.65s 
Record: #5,005 Memory: 1,355,200kb taking 2.94s 
Record: #6,006 Memory: 1,355,376kb taking 3.28s 
Record: #7,007 Memory: 1,355,176kb taking 3.56s 
Record: #8,008 Memory: 1,355,408kb taking 3.81s 
Record: #9,009 Memory: 1,355,464kb taking 4.07s 
Record: #10,010 Memory: 1,355,392kb taking 4.32s 
Record: #11,011 Memory: 1,355,352kb taking 4.63s 
Record: #12,012 Memory: 1,355,376kb taking 4.90s 
Record: #13,013 Memory: 1,355,200kb taking 5.14s 
Record: #14,014 Memory: 1,355,184kb taking 5.43s 
Record: #15,015 Memory: 1,355,344kb taking 5.72s 

फ़ाइल, दुर्भाग्य से, समय पूरी बात वृद्धि की दर से पढ़ा जाता है के आसपास ~ 20GB तो मैं शायद मर चुका हो जाएगा है:

यहाँ धीरे-धीरे बदतर हो रही यह के उत्पादन में है। कोड नीचे (मुख्य रूप से) है लेकिन मुझे संदेह है कि यह fgets() के साथ कुछ करने के लिए है, लेकिन मुझे यकीन नहीं है कि क्या।

$handle = fopen ($import_file, 'r'); 

    while ($line = fgets ($handle)) 
    { 
     $data = json_decode ($line); 

     save_record ($data, $line); 
    } 

अग्रिम धन्यवाद!

संपादित करें:

बाहर टिप्पणी करते हुए 'save_record ($ डेटा, $ लाइन);' कुछ भी नहीं प्रतीत होता है।

+0

क्या आप save_record के लिए कोड पोस्ट कर सकते हैं? शायद यह कुंजी – Jhong

+0

असल में अगर मैं save_record() लाइन पर टिप्पणी करता हूं तो यह अभी भी उतना ही खराब है। – DCD

+1

आप उस प्रदर्शन आउटपुट को कैसे प्राप्त कर रहे हैं? आपके द्वारा प्रदान किए गए कोड नमूने में आपके पास कोई प्रदर्शन लॉगिंग नहीं है। मुझे संदेह है कि समस्या कहीं और है। क्या आपके पास कुछ और कोड है जो आप हमें नहीं दिखा रहे हैं जो प्रासंगिक हो सकता है? –

उत्तर

0

http://php.net/manual/en/function.fgets.php

लेह Purdie टिप्पणी के अनुसार, वहाँ fgets साथ बड़ी फ़ाइलों पर कुछ प्रदर्शन मुद्दा है। अपने JSON ऑब्जेक्ट के अपने परीक्षण लाइनों से भी बड़ा कर रहे हैं, तो आप इसे शायद सीमा बहुत तेजी से

उपयोग http://php.net/manual/en/function.stream-get-line.php और लंबाई सीमा

0

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

आपने समय प्राप्त करने के लिए कुछ या अन्य का वाद्य यंत्र किया। सुनिश्चित करें कि वे अकेले 15000 बार या तो उन्हें निष्पादित करके कोई समस्या नहीं पैदा कर सकते हैं।

1

कभी-कभी इन बड़ी फ़ाइलों को पढ़ने के लिए सिस्टम कमांड का उपयोग करना बेहतर होता है। मैं ऐसी ही कुछ में पड़ गए और यहाँ एक छोटे चाल मैं प्रयोग किया जाता है:

$lines = exec("wc -l $filename"); 
for($i=1; $i <= $lines; $i++) { 
    $line = exec('sed \''.$i.'!d\' '.$filename); 

    // do what you want with the record here 
} 

मैं फ़ाइलों को भरोसा नहीं किया जा सकता है के साथ इस की सिफारिश नहीं होगा, लेकिन यह तेजी से चलाता है के बाद से यह एक समय में एक रिकॉर्ड खींचती प्रणाली का उपयोग कर। उम्मीद है की यह मदद करेगा।

+0

+1 अच्छा विचार, मैं इसे भविष्य में मानता हूं। – alex

0

मुझे यह प्रश्न मिला कि मुझे 9 6 जी टेक्स्ट फ़ाइल के माध्यम से और अधिक तेज़ी से जाने के लिए रास्ता खोजने का प्रयास किया गया। प्रारंभ में लिखी गई लिपि में 0.1% तक पहुंचने के लिए 15 घंटे लग गए ...

मैंने स्ट्रीम_get_लाइन, fgets और sed के लिए exec का उपयोग करके यहां सुझाए गए कुछ समाधानों का प्रयास किया है। मैं एक अलग दृष्टिकोण के साथ समाप्त हुआ कि मैंने सोचा कि मैं इस सवाल से रोककर किसी और के साथ साझा करूंगा।

फ़ाइल को विभाजित करें! :-)

मेरे फ्रीब्स बॉक्स (लिनक्स और अन्य के लिए भी मौजूद है) पर मेरे पास 'स्प्लिट' नामक एक कमांड लाइन उपयोगिता है।

 
usage: split [-l line_count] [-a suffix_length] [file [prefix]] 
     split -b byte_count[K|k|M|m|G|g] [-a suffix_length] [file [prefix]] 
     split -n chunk_count [-a suffix_length] [file [prefix]] 
     split -p pattern [-a suffix_length] [file [prefix]] 

तो मैं भागा:

 
split -l 25000 -a 3 /data/var/myfile.log /data/var/myfile-log/ 

तब मैं/डेटा/var/myFile-लॉग/निर्देशिका में 5608 फ़ाइलें, जो तब सब एक आदेश के साथ समय में एक से संसाधित किया जा सकता है के साथ समाप्त हो गया जैसे:

 
php -f do-some-work.php /data/var/myfile-log/*