2013-03-14 12 views
10

मैं इन दो समान आदेशों के बीच अंतर को समझने की कोशिश कर रहा हूं।कमांड प्रतिस्थापन बनाम प्रक्रिया प्रतिस्थापन

aa=$(foo | bar | head -1) 
read aa < <(foo | bar | head -1) 
  • मुझे पता है कि <()#!/bin/bash आवश्यकता है, लेकिन यह है कि यह धीमी है?
  • क्या वे समान मात्रा में सबशेल्स बनाते हैं?
  • वे bash या sh प्रक्रियाओं की एक ही राशि की आवश्यकता होती है है?

मैं सर्वश्रेष्ठ प्रदर्शन के साथ आदेश का उपयोग करने के लिए देख रहा हूँ।

उत्तर

6
  1. सं बैश तेजी से गैर POSIX मोड में है।
  2. यह निर्भर करता है। यह एक कार्यान्वयन-विशिष्ट और मंच-विशिष्ट विवरण दोनों है।
    • बैश में, दोनों प्रक्रियाओं की एक ही नंबर की आवश्यकता है।यदि lastpipe सक्षम नहीं है, तो प्रत्येक पाइपलाइन तत्व के लिए एक प्रक्रिया है, साथ ही प्रतिस्थापन और मूल प्रक्रिया के लिए एक सबहेल भी है।
    • बैश में, यदि lastpipe सक्षम है, तो पाइपलाइन का अंतिम तत्व exec दोनों मामलों में फोर्क किए बिना, अभी भी प्रक्रियाओं की एक ही संख्या की आवश्यकता होगी।
    • ksh93 में, दोनों को इस मामले में प्रक्रियाओं की एक ही संख्या की आवश्यकता होनी चाहिए, लेकिन यदि अंतिम पाइपलाइन तत्व एक अंतर्निहित था, तो यह कमांड प्रतिस्थापन के लिए माता-पिता की प्रक्रिया में भाग लेगा, जिससे इसे और भी तेज बना दिया जा सकेगा।
    • दोनों बैश और ksh93 में, यदि शेल को उस सिस्टम पर संकलित किया गया है जो /dev/fd/* का समर्थन नहीं करता है, तो शेल प्रक्रिया प्रतिस्थापन के लिए नामित पाइप बनायेगा। यह संभवतः प्रदर्शन को प्रभावित करता है।
  3. पिछली गोली शायद यहां जाना चाहिए। नोट "सबहेल" अनिवार्य रूप से एक अलग प्रक्रिया को इंगित नहीं करता है, हालांकि लगभग सभी गोले में, यह करता है ($(<...) के अपवाद के साथ बैश को छोड़कर सबकुछ में)। Mksh और ksh93 में, ${ ;} शैली कमांड प्रतिस्थापन भी है, लेकिन प्रत्येक खोल इसे अलग-अलग लागू करता है। Ksh93 में, यह एक गति प्रदान कर सकता है या नहीं। mksh में, शायद नहीं। mksh प्रक्रिया प्रतिस्थापन का समर्थन नहीं करता है, और zsh समर्थन नहीं करता है (और अनुकरण करने का कोई तरीका नहीं है) BASHPID, इसलिए मैंने इसे नहीं देखा है।

आंतरिक रूप से तेजी से बैश में एक प्रक्रिया प्रतिस्थापन की तुलना में एक आदेश प्रतिस्थापन के बारे में कुछ भी नहीं है, लेकिन headread के मामले में अनावश्यक के बाद से आप केवल वहाँ एक पंक्ति पढ़ रहे है। एक तरफ के रूप में, हमेशा head -n ... - -1 पोर्टेबल नहीं है। इसके अलावा, read का उपयोग -r के बिना न करें जब तक कि आप इनपुट को उलझाना चाहते हैं।

2

Bash's के साथ बेंचमार्किंग time में निर्मित, पहला फॉर्म दूसरे की तुलना में धीमा है।

आप इसे खुद के साथ परीक्षण कर सकते हैं:

bash -c 'time PIPELINE...' 

दोनों subshells बना सकते हैं - खोल पढ़ने और पहले मामले में एक subshell के उत्पादन में विस्तार हो रहा है, और एक पृष्ठभूमि से खोल के read builtin पढ़ने के साथ दूसरे में प्रक्रिया।

देखें:

+1

एचएम, यह कहा गया है कि यह बिल्कुल सही नहीं है। आशा है कि आपको बुरा लगेगा कि मैंने आपके लिए थोड़ा सा बदलाव किया है। दोनों मामलों में "फाइल डिस्क्रिप्टर" शामिल हैं, और दोनों हमेशा एक सबहेल उत्पन्न करते हैं, जो कम से कम बैश में भी कम से कम एक कांटा का तात्पर्य है। मेरे अधिक सामान्यीकृत परीक्षणों में, "read -rx <<(...)' "और" 'x = $ (...) '" के बीच का अंतर लगभग छोटे इनपुट के साथ पुनरावर्तनीय है, और एकल बड़े इनपुट के लिए , असाइनमेंट थोड़ा तेज़ (अपेक्षित के रूप में) होने के साथ, लेकिन मूल प्रश्न में दोनों समाधान अजीब और उप-इष्टतम थे। – ormaaj

+0

कोई समस्या नहीं 'भाई, संपादन के लिए धन्यवाद। –

1

यहां प्रदर्शन में सुधार करने का सबसे अच्छा तरीका के रूप में ज्यादा के रूप में आप कर सकते हैं कांटे और पाइप से छुटकारा पाने के लिए है।

सभी इरादों और उद्देश्यों के लिए, आप के रूप में कहा गया है प्रदर्शन के मुद्दों के बारे में चिंता नहीं करनी चाहिए। निष्पादन समय का 99% विशेष आदेशों द्वारा निर्धारित किया जा सकता है, प्रक्रिया-प्रतिस्थापन बनाम कमांड-प्रतिस्थापन में अंतर नहीं। क्या आप अनुकूलन का पहला कानून जानते हैं? मत करो। विशेष रूप से यदि आप पोर्टेबिलिटी बलिदान कर रहे हैं। $(whatever) का उपयोग करें और बाकी सब कुछ भूल जाओ। यदि आप वास्तव में प्रदर्शन के बारे में चिंता करते हैं, तो यह आदेश/पाइप/कांक्स जिन्हें आपको संबोधित करने की आवश्यकता है। अन्यथा आप अपनी आंखों से आँसू निचोड़कर वजन कम करने की कोशिश कर रहे हैं।

1

प्रक्रिया प्रतिस्थापन piplines/आदेश प्रतिस्थापन द्वारा बनाई subshells नजरअंदाज। प्रतिस्थापन वाक्यविन्यास को फीफो या एफडी के नाम से प्रतिस्थापित किया जाता है, और इसके अंदर का आदेश पृष्ठभूमि में चलाया जाता है। प्रतिस्थापन एक ही समय में पैरामीटर विस्तार और कमांड प्रतिस्थापन के रूप में किया जाता है। प्रक्रिया प्रतिस्थापन पर

जानकारी बाहर चेक के साथ "टी" के रूप में अच्छी तरह से इस्तेमाल किया।

http://mywiki.wooledge.org/ProcessSubstitution

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