लूप बनाम विस्तार का प्रदर्शन


9

नीचे तुलना पर विशेषज्ञ के सुझाव की आवश्यकता है:

लूप का उपयोग करके कोड सेगमेंट:

for file in `cat large_file_list`
do
    gzip -d $file
done

सरल विस्तार का उपयोग कर कोड खंड:

gzip -d `cat large_file_list`

कौन सा तेज होगा? बड़े डेटा सेट में हेरफेर करना है।


1
सही उत्तर इस बात पर निर्भर करेगा कि gzipआपके सिस्टम को शुरू होने में कितना समय लगता है, फाइल सूची में फाइलों की संख्या और उन फाइलों का आकार।
Kusalananda

फ़ाइल सूची में लगभग 1000 - 10000 फाइलें होंगी। आकार कुछ किलोबाइट से 500 एमबी तक भिन्न होता है। मुझे नहीं पता कि मेरे सिस्टम में गज़िप शुरू करने में कितना समय लगता है। किसी भी तरह की जाँच?
लियोन

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

लियोन मेरे परीक्षा परिणामों पर एक नज़र डालते हैं: "विशाल-आर्गलिस्ट" मेरी सेटिंग में "लूप" से 20 गुना तेज है।

प्रक्रिया शुरू होने और कमांड लाइन की लंबाई के बीच एक खुशहाल माध्यम के लिए, कुछ का उपयोग करें, xargs gzip -d < large_file_listलेकिन फ़ाइल नाम में रिक्त स्थान के लिए बाहर देखो, शायद साथtr \\n \\0 large_file_list | xargs -0 gzip -d
w00t

जवाबों:


19

जटिलताओं

निम्नलिखित केवल कभी-कभी काम करेगा:

gzip -d `cat large_file_list`

तीन समस्याएं हैं ( bashऔर अधिकांश अन्य बॉर्न जैसे गोले):

  1. यह विफल हो जाएगा अगर किसी फ़ाइल नाम में स्पेस टैब या न्यूलाइन वर्ण हैं (यह मानते हुए कि $IFSसंशोधित नहीं किया गया है)। इसका कारण शेल शब्द का विभाजन है

  2. यह विफल करने के लिए भी उत्तरदायी है यदि किसी फ़ाइल नाम में इसमें ग्लोब-सक्रिय वर्ण हैं। ऐसा इसलिए है क्योंकि शेल फ़ाइल सूची में pathname विस्तार लागू करेगा ।

  3. यह भी विफल हो जाएगा यदि फ़ाइल नाम से शुरू होता है -(यदि POSIXLY_CORRECT=1वह केवल पहली फ़ाइल पर लागू होता है) या यदि कोई फ़ाइल नाम है -

  4. यह भी विफल हो जाएगा अगर एक कमांड लाइन पर फिट होने के लिए इसमें बहुत सारे फ़ाइल नाम हैं।

नीचे दिया गया कोड ऊपर की तरह ही समस्याओं के अधीन है (चौथे को छोड़कर)

for file in `cat large_file_list`
do
    gzip -d $file
done

विश्वसनीय समाधान

यदि आपकी large_file_listप्रति पंक्ति में एक फ़ाइल का नाम है, और एक फ़ाइल -उनके बीच नहीं है, और आप एक GNU सिस्टम पर हैं, तो उपयोग करें:

xargs -rd'\n' gzip -d -- <large_file_list

-d'\n'xargsइनपुट की प्रत्येक पंक्ति को एक अलग फ़ाइल नाम के रूप में व्यवहार करना बताता है।

-rxargsयदि इनपुट फ़ाइल खाली है, तो कमांड नहीं चलाना बताता है।

--बताता है gzipकि निम्न तर्कों को विकल्प के रूप में नहीं माना जाना चाहिए, भले ही वे किसके साथ शुरू हों --अकेले हालांकि अभी भी -फाइल के बजाय के रूप में इलाज किया जाएगा -

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


विस्तृत उत्तर के लिए धन्यवाद। मैं आपके बताए 3 मुद्दों को समझता हूं। फ़ाइल का नाम सरल है और उन चुनौतियों का सामना नहीं करेगा क्योंकि सूची 20000 तक होगी। और मेरा प्रश्न मूल रूप से उन दो खंडों के प्रदर्शन पर है। धन्यवाद।
लियोन

1
@ लॉयन forपाश सबसे दूर होगा - सबसे धीमा। अन्य दो विधियां एक-दूसरे की गति के बहुत करीब होंगी।
जॉन १०२४ २४

7
इसके अलावा, संभावित समस्याओं को खारिज न करें: StackExchange पर यहाँ कई सवाल हैं क्योंकि शब्द विभाजन या pathname विस्तार उन लोगों के लिए हुआ, जो इसकी उम्मीद नहीं कर रहे थे।
जॉन 1024

5
यह भी ध्यान दें कि किसी फ़ाइल को पढ़ने पर भिन्नता है xargs: कम से कम GNU संस्करण में --arg-fileविकल्प (संक्षिप्त रूप -a) है। इसलिए xargs -a large_file_list -rd'\n' gzip -d इसके बदले कोई कर सकता था। प्रभावी रूप से, इसमें कोई अंतर नहीं है, इस तथ्य से अलग कि <शेल ऑपरेटर है और xargsस्टैडेन (जो शेल "लिंक" से फाइल करने के लिए) से पढ़ेगा, जबकि स्पष्ट रूप से फाइल को प्रश्न में खोल -aदेगाxargs
सर्जियो कोलोडियाज़नी

2
टेराडॉन ने parallelकई प्रतियों का उपयोग करने के बारे में एक और टिप्पणी में उल्लेख किया gzip, लेकिन xargs(कम से कम जीएनयू एक), इसके लिए भी -Pस्विच है। मल्टीकोर मशीनों पर जो फर्क कर सकते हैं। लेकिन यह भी संभव है कि सड़न पूरी तरह से I / O- बाध्य हो।
ilkachachu

12

मुझे संदेह है कि यह बहुत मायने रखेगा।

मैं एक लूप का उपयोग करता हूं, सिर्फ इसलिए कि मुझे नहीं पता है कि सूची फ़ाइल में कितनी फाइलें सूचीबद्ध हैं, और मुझे नहीं पता (आम तौर पर) पता है कि क्या किसी भी फ़ाइल नाम में उनके स्थान हैं। एक कमांड प्रतिस्थापन जो तर्क की एक बहुत लंबी सूची उत्पन्न करेगा "परिणाम सूची बहुत लंबी" त्रुटि हो सकती है जब उत्पन्न सूची की लंबाई बहुत लंबी है।

मेरा लूप कैसा लगेगा

while IFS= read -r name; do
    gunzip "$name"
done <file.list

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

while IFS= read -r name; do
    zcat "$name" | process_data
done <file.list

(जहां process_dataकुछ पाइपलाइन है जो मानक इनपुट से असंपीड़ित डेटा पढ़ती है)

यदि डेटा के प्रसंस्करण को इसके बारे में अनियंत्रित होने से अधिक समय लगता है, तो यह सवाल कि क्या लूप अधिक कुशल है या अप्रासंगिक नहीं है।

आदर्श रूप से , मैं हालांकि, फ़ाइल नाम की सूची से काम नहीं करना पसंद करूंगा, और इसके बजाय, फ़ाइल नाम का उपयोग करते हुए ग्लोबिंग पैटर्न

for name in ./*.gz; do
    # processing of "$name" here
done

जहाँ ./*.gzकुछ पैटर्न है जो प्रासंगिक फाइलों से मेल खाता है। इस तरह हम फाइलों की संख्या के आधार पर नहीं हैं और न ही फाइलनाम में उपयोग किए जाने वाले पात्रों पर निर्भर करते हैं (उनमें नईलाइन या अन्य व्हाट्सएप अक्षर हो सकते हैं, या डैश के साथ शुरू हो सकते हैं, आदि)

सम्बंधित:


5

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

लेकिन, मैं अनुकूलन के सुनहरे नियम की याद दिलाना चाहता हूं : इसे समय से पहले न करें।

  1. इससे पहले कि आप यह जानते हैं कि समस्या है, उस प्रकार का अनुकूलन न करें।

    क्या कार्यक्रम के इस भाग में लंबा समय लगता है? ठीक है, बड़ी फ़ाइलों को डिकम्पोज करना संभव है, और आप इसे वैसे भी करने जा रहे हैं, इसलिए इसका जवाब देना आसान नहीं होगा।

  2. का आकलन करें। वास्तव में, यह सुनिश्चित करने का सबसे अच्छा तरीका है।

    आप अपनी खुद की आँखों (या अपनी खुद की स्टॉपवॉच) के साथ परिणाम देखेंगे, और वे आपकी स्थिति पर लागू होंगे जो इंटरनेट पर यादृच्छिक उत्तर नहीं हो सकता है। स्क्रिप्ट में दोनों वेरिएंट डालें और चलाएं time script1.sh, और time script2.sh। (ओवरहेड की निरपेक्ष राशि को मापने के लिए खाली संपीड़ित फ़ाइलों की सूची के साथ ऐसा करें।)


0

आपकी डिस्क कितनी तेज़ है?

यह आपके सभी CPU का उपयोग करना चाहिए:

parallel -X gzip -d :::: large_file_list

तो आपकी सीमा आपके डिस्क की गति होने की संभावना है।

आप के साथ समायोजन की कोशिश कर सकते हैं -j:

parallel -j50% -X gzip -d :::: large_file_list

यह पिछली कमांड के समान समानांतर में आधे काम चलाएगा, और आपकी डिस्क को कम तनाव देगा, इसलिए आपकी डिस्क के आधार पर यह तेज हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.