“Ls *” “ls” से अधिक समय क्यों लेता है?


28

मेरे पास एक निर्देशिका में कुछ फाइलें हैं:

$ ls | wc -l
9376

क्या कोई समझा सकता है कि उपयोग करने में इतना बड़ा समय अंतर क्यों है ls *और ls?

$ time ls > /dev/null
real    0m0.118s
user    0m0.106s
sys     0m0.011s

तथा

$ time ls * > /dev/null
real    1m32.602s
user    0m0.233s
sys     0m0.438s

ठीक है, यह एक कठोर उदाहरण है और शायद बढ़ाया गया है क्योंकि निर्देशिका एक सामान्य समानांतर फ़ाइल सिस्टम (GPFS) पर है। लेकिन मैं एक स्थानीय फ़ाइल सिस्टम पर एक महत्वपूर्ण मंदी देख सकता हूं।

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

$ time ls -l > /dev/null
real    0m58.772s
user    0m0.113s
sys     0m0.452s
$ time ls -l * > /dev/null
real    1m19.538s
user    0m0.252s
sys     0m0.461s

और मुझे यह जोड़ना चाहिए कि मेरे उदाहरण में कोई उप निर्देशिका नहीं हैं:

$ diff <(ls) <(ls *)
$

जवाबों:


47

जब आप lsतर्क के बिना चलते हैं, तो यह सिर्फ एक निर्देशिका खोलेगा, सभी सामग्रियों को पढ़ेगा, उन्हें छांटेगा और उनका प्रिंट आउट लेगा।

जब आप चलाते हैं ls *, तो पहले शेल का विस्तार होता है *, जो प्रभावी रूप से वही होता है जो साधारण lsने किया था, वर्तमान निर्देशिका में सभी फाइलों के साथ एक तर्क वेक्टर बनाता है और कॉल करता है lslsफिर उस तर्क सदिश और प्रत्येक तर्क के लिए प्रक्रिया करनी होती है, और access(2)यह अस्तित्व की जाँच करने के लिए फ़ाइल को कॉल करता है। फिर यह पहले (सरल) के समान आउटपुट का प्रिंट आउट लेगा ls। बड़े तर्क वेक्टर के शेल के प्रसंस्करण दोनों lsमें छोटे ब्लॉकों के मेमोरी आवंटन की बहुत अधिक संभावना होगी, जिसमें कुछ समय लग सकता है। हालाँकि, चूंकि थोड़ा sysऔर userसमय था, लेकिन बहुत realसमय, अधिकांश समय डिस्क के लिए इंतजार करने में खर्च किया जाता था, बजाय सीपीयू मेमोरी आवंटन के उपयोग के।

access(2)अनुमति जानकारी प्राप्त करने के लिए प्रत्येक कॉल को फ़ाइल के इनोड को पढ़ने की आवश्यकता होगी। इसका मतलब है कि एक बहुत अधिक डिस्क पढ़ता है और बस एक निर्देशिका को पढ़ने की तुलना में चाहता है। मुझे नहीं पता कि ये ऑपरेशन आपके GPFS पर कितने महंगे हैं, लेकिन जैसा कि आपने दिखाया ls -lहै कि वाइल्डकार्ड केस के समान रन टाइम है, इनोड की जानकारी प्राप्त करने के लिए आवश्यक समय हावी दिखाई देता है। यदि प्रत्येक रीड ऑपरेशन पर GPFS की आपके स्थानीय फाइल सिस्टम की तुलना में थोड़ी अधिक विलंबता है, तो हम इन मामलों में इसके अधिक स्पष्ट होने की उम्मीद करेंगे।

वाइल्डकार्ड मामले और ls -l50% के बीच अंतर को डिस्क पर इनोड्स के आदेश द्वारा समझाया जा सकता है। यदि इनोड को क्रमबद्ध रूप से उसी क्रम में रखा गया है, जैसे डायरेक्टरी और ls -lस्टेटमेंट में फाइलनेम (2) सॉर्ट करने से पहले डाइरेक्टरी ऑर्डर में फाइल एड करते हैं, ls -lतो संभवत: स्वीप में अधिकतर इनोड्स पढ़ेंगे। वाइल्डकार्ड के साथ, शेल उन्हें पास करने से पहले फ़ाइलनाम को सॉर्ट करेगा ls, इसलिए lsसंभवतः डिस्क को एक अलग क्रम में पढ़ा जाएगा, और अधिक डिस्क हेड मूवमेंट को जोड़ा जाएगा।

यह ध्यान दिया जाना चाहिए कि आपके timeआउटपुट में वाइल्डकार्ड का विस्तार करने के लिए शेल द्वारा लिया गया समय शामिल नहीं होगा।

यदि आप वास्तव में देखना चाहते हैं कि क्या हो रहा है, तो उपयोग करें strace(1):

strace -o /tmp/ls-star.trace ls *
strace -o /tmp/ls-l-star.trace ls -l *

और एक नज़र है कि प्रत्येक मामले में कौन से सिस्टम कॉल किए जा रहे हैं।

If मुझे नहीं पता कि access(2)क्या वास्तव में उपयोग किया जाता है, या कुछ और जैसे कि stat(2)। लेकिन दोनों को शायद एक इनकोड लुकअप की आवश्यकता होती है (मुझे यकीन नहीं है कि अगर access(file, 0)कोई इनोड लुकअप को बायपास कर देगा।)


2
अच्छा जवाब, मैं बस एक समान पोस्ट करने के बारे में था :) लेकिन हाँ, यह सही है, यह सभी लूपिंग में दक्षता के बारे में है, lsयह सिर्फ फाइल सिस्टम से पूछ सकता है "इनोड के बच्चे क्या हैं pwd" जहां के साथ ls *यह पूछने के लिए है कि "इनोड के बच्चे (और फाइल क्या है) क्या हैं a" इसके बाद b, c, d, आदि आदि हैं। एक क्वेरी बनाम कई।
एनजे

@NJ एक क्वेरी बनाम कई अब तक का एक अच्छा सारांश है। @camh: विस्तृत जवाब के लिए धन्यवाद। मैंने ls -l(साथ ही अब भी लगभग 30 सेकंड कम ls *) के आउटपुट को पोस्ट किया
सेबस्टियन

@ सेबैस्टियन जैसा कि कैम ने कहा, टाइमस्टैम्प / मालिक की जानकारी / अनुमति आदि के बारे में जानकारी प्राप्त करने के लिए प्रत्येक फाइल की ls -lतुलना lsमें अधिक समय लगेगाstat(2)
एनजे

6
मत भूलो, वर्तमान निर्देशिका में सभी प्रविष्टियों *को ग्लोब जो एक अवधि के साथ शुरू नहीं होते हैं - उपनिर्देशिकाओं के नाम सहित। जिसके बाद ed एड ’ होगा । ls
शादुर

@camh: मैं थोड़ा और परीक्षण किया (मेरे संपादन देखें) और पाया गया कि: ls< ls -l< ls -l *< ls *(मैं हमेशा यह तीन बार भाग गया)। अपने विवरण के साथ, मुझे समझ नहीं आता क्यों ls -l *की तुलना में तेजी हैls *
सेबस्टियन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.