2016-03-29 3 views
5

मुझे libxml-ruby मणि का उपयोग कर 500 एमबी एक्सएमएल फ़ाइल पार्सिंग कोड का एक टुकड़ा मिला है। मेरे लिए आश्चर्य की बात है, यह कोड धीमा जीसी अक्षम के साथ चलाता है, जो काउंटर-अंतर्ज्ञानी लगता है। कारण क्या हो सकता है? मैंने बहुत सारी मेमोरी उपलब्ध कराई है और सिस्टम स्वैपिंग नहीं कर रहा है।यह एक्सएमएल पार्सिंग क्यों रूबी कोड जीसी अक्षम के साथ धीमा चलता है?

ruby  gc on gc off 
2.2.0 16.93s 18.81s 
2.1.5 16.22s 18.58s 
2.0.0 17.63s 17.99s 

क्यों कचरा कलेक्टर निष्क्रिय कर दें:

require 'xml' 

#GC.disable 

@reader = XML::Reader.file('books.xml', :options => XML::Parser::Options::NOBLANKS) 

@reader.read 
@reader.read 

while @reader.name == 'book' 
    book_id = @reader.get_attribute('id') 
    @reader.read 

    until @reader.name == 'book' && @reader.node_type == XML::Reader::TYPE_END_ELEMENT 
    case @reader.name 
    when 'author' 
     author = @reader.read_string 
    when 'title' 
     title = @reader.read_string 
    when 'genre' 
     genre = @reader.read_string 
    when 'price' 
     price = @reader.read_string 
    when 'publish_date' 
     publish_date = @reader.read_string 
    when 'description' 
     description = @reader.read_string 
    end 
    @reader.next 
    end 

    @reader.read  

end 
@reader.close 

यहाँ परिणाम मुझे मिल रहे हैं? मैंने Ruby Performance Optimization पुस्तक में पढ़ा है कि रूबी ज्यादातर धीमी है क्योंकि प्रोग्रामर मेमोरी खपत के बारे में नहीं सोचते हैं, जिससे कचरा कलेक्टर बहुत निष्पादन समय का उपयोग करता है। इस प्रकार जीसी को बंद करना तुरंत चीजों को गति देना चाहिए (पाठ्यक्रम की स्मृति उपयोग की लागत पर), जब तक कि सिस्टम स्वैपिंग नहीं कर रहा हो।

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

libxml-ruby मणि हुड के तहत मूल सी LibXML कार्यान्वयन का उपयोग करता है - क्या यह कारण हो सकता है?

फ़ाइल है कि मैं प्रयोग किया जाता है मैन्युअल books.xml नमूना कुछ माइक्रोसॉफ्ट प्रलेखन से डाउनलोड multiplicated है:

<catalog> 
<book id="bk101"> 
    <author>John Doe</author> 
    <title>XML for dummies</title> 
    <genre>Computer</genre> 
    <price>44.95</price> 
    <publish_date>2000-10-01</publish_date> 
    <description>Some description</description> 
</book> 
.... 
</catalog> 

मेरे सेटअप: OS X Yosemite, इंटेल कोर i5 2.6 गीगा, राम के 16GB।

किसी भी सुझाव के लिए धन्यवाद।

+0

@engineersmnky अगर वह पूछ रहा है कि इसे तेज़ी से कैसे बनाया जाए, तो यह कोड समीक्षा पर नहीं, यहां है। अगर वह इसके साथ मदद चाहता है, तो उसे वहां जाना चाहिए। – Riker

+0

@engineersmnky "कारण क्या हो सकता है?मैंने बहुत सारी मेमोरी उपलब्ध कराई है और सिस्टम स्वैपिंग नहीं कर रहा है। " – Riker

+1

@engineersmnky नीचे कुछ और देखें, जो कहता है," क्या मुझे कोड के किसी भी या सभी पहलुओं के बारे में फीडबैक चाहिए? "ओपी ऐसा नहीं चाहता फीडबैक –

उत्तर

1

आप ऑपरेटिंग सिस्टम को भूल रहे हैं - आपने अपनी एमआरआई प्रक्रिया में जीसी को अक्षम कर दिया है लेकिन आपके पास लिनक्स/यूनिक्स कर्नेल पर कोई नियंत्रण नहीं है और यह आपके एमआरआई एप्लिकेशन में मेमोरी आवंटित करता है।

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

आपका स्रोत डेटा 500 एमबी एक्सएमएल फ़ाइल है जिसे आप पढ़ रहे हैं, नोड द्वारा नोड, अपने एमआरआई प्रोग्राम की मेमोरी पदचिह्न में। ऐसा लगता है कि आपकी एमआरआई प्रक्रिया प्रसंस्करण के समय तक कई जीबी डेटा खपत करती है; और आपके मुख्य रीडिंग ब्लॉक में किसी भी मान को प्रत्येक पुनरावृत्ति के बाद त्याग दिया जाता है - वे बस स्मृति में चारों ओर लटकाते हैं, और जब आपका एप्लिकेशन निकलता है और स्मृति को ऑपरेटिंग सिस्टम पर वापस सौंप दिया जाता है तो अंत में साफ हो जाता है।

जीसी इसका प्रबंधन करने के लिए जगह पर है; यह आपके अनुप्रयोग को कर्नेल से अतिरिक्त मेमोरी का अनुरोध करने से रोकने के लिए है, जब तक कि इसे बिल्कुल इसकी आवश्यकता न हो, और आपके एप्लिकेशन को कारण के भीतर आवंटित स्मृति के भीतर "पर्याप्त" चलाने की अनुमति दें।

तो मैं ईमानदारी से आश्चर्यचकित नहीं हूं कि आप जीसी अक्षम के साथ मंदी देखते हैं। आपके बेंचमार्क के दौरान लोड औसत और आपके बॉक्स का स्वैप उपयोग क्या होगा।

+0

ओएस आवंटन ओवरहेड के साथ सुझाव के लिए धन्यवाद। मैं कुछ अतिरिक्त मानक यह ध्यान में रखते हैं। – mjkpl

+0

संभवतः आप सही हैं। मैं देख सकता हूं कि प्रक्रिया लगातार बढ़ती जा रही है और अधिक स्मृति में आवंटित हो रही है। अपना बिंदु साबित करने के लिए मैंने प्रक्षेपण करने का एक तरीका ढूंढ लिया शुरुआत में स्मृति की बड़ी मात्रा का पता लगाएं (जैसे जावा में '-Xmx' स्विच), ताकि निष्पादन के दौरान उस पर किसी भी समय बिताना आवश्यक नहीं होगा। लेकिन जाहिर है रूबी में यह संभव नहीं है। – mjkpl

संबंधित मुद्दे