2012-01-19 8 views
19

मैं बड़ी हार्ड डिस्क पर पाइथन में फ़ाइल लुकअप के साथ गड़बड़ कर रहा हूं। मैं os.walk और glob देख रहा हूँ। मैं आमतौर पर os.walk का उपयोग करता हूं क्योंकि मुझे यह बहुत साफ लगता है और यह तेज (सामान्य आकार निर्देशिकाओं के लिए) लगता है।os.walk या glob के लिए जल्दी?

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

core = re.compile(r"core\.\d*") 
for root, dirs, files in os.walk("/path/to/dir/") 
    for file in files: 
     if core.search(file): 
      path = os.path.join(root,file) 
      print "Deleting: " + path 
      os.remove(path) 

या

for file in iglob("/path/to/dir/core.*") 
    print "Deleting: " + file 
    os.remove(file) 
+3

मेरे लिए समय से पहले अनुकूलन की तरह लगता है। मैंने स्रोत पर देखा (http://hg.python.org/cpython/file/d01208ba482f/Lib/glob.py और http://hg.python.org/cpython/file/d01208ba482f/Lib/os.py) और देखें कि दोनों कार्य 'os.listdir' और' os.isdir' पर भरोसा करते हैं, इसलिए मेरा आंत मुझे बताता है कि आपको एक या दूसरे तरीके से लाभ नहीं मिलेगा। (हालांकि, जैसा कि नीचे दिए गए दो उत्तरों में बताया गया है, 'os.walk' उपनिर्देशिकाओं पर recurses और' glob.iglob' नहीं है, इसलिए यह तुलना करने के लिए समझ में नहीं आता है)। यदि आप प्रदर्शन समस्या के साथ समाप्त होते हैं, तो कुछ दृष्टिकोण देखें। अन्यथा, बस स्पष्ट कोड लिखें। –

उत्तर

13

साथ जाना होगा मैं 1000 dirs में वेब पृष्ठों का एक छोटा सा कैश पर एक शोध कर दिया। कार्य डीआईआर में फाइलों की कुल संख्या गिनना था। उत्पादन होता है:

os.listdir: 0.7268s, 1326786 files found 
os.walk: 3.6592s, 1326787 files found 
glob.glob: 2.0133s, 1326786 files found 

जैसा कि आप देख, os.listdir तीन का सबसे तेज है।और इस कार्य के लिए glog.glob अभी भी os.walk से तेज़ है।

स्रोत:

import os, time, glob 

n, t = 0, time.time() 
for i in range(1000): 
    n += len(os.listdir("./%d" % i)) 
t = time.time() - t 
print "os.listdir: %.4fs, %d files found" % (t, n) 

n, t = 0, time.time() 
for root, dirs, files in os.walk("./"): 
    for file in files: 
     n += 1 
t = time.time() - t 
print "os.walk: %.4fs, %d files found" % (t, n) 

n, t = 0, time.time() 
for i in range(1000): 
    n += len(glob.glob("./%d/*" % i)) 
t = time.time() - t 
print "glob.glob: %.4fs, %d files found" % (t, n) 
12

आप उपनिर्देशिकाएं के माध्यम से recurse करने, os.walk का उपयोग की जरूरत है। अन्यथा, मुझे लगता है कि glob.iglob या os.listdir का उपयोग करना आसान होगा।

+1

+1। खासकर एक समारोह को इंगित करने के लिए उपनिर्देशिका के माध्यम से पुनरावृत्ति करता है जबकि दूसरा नहीं करता है। –

+0

@aculich। सुधारों के लिए धन्यवाद। –

+3

@ स्टेवन, ग्लोब पैटर्न '/ path/to/*/core' वाइल्डकार्ड के रूप में' * 'का उपयोग करता है। 'ग्लोब' केवल एक निर्देशिका के साथ '*' को प्रतिस्थापित करेगा। यह अभी भी सभी उपनिर्देशिकाओं के माध्यम से * रिकर्स * नहीं करता है। – unutbu

1

आप os.walk का उपयोग कर सकते हैं और अभी भी ग्लोब-स्टाइल मिलान का उपयोग कर सकते हैं।

for root, dirs, files in os.walk(DIRECTORY): 
    for file in files: 
     if glob.fnmatch.fnmatch(file, PATTERN): 
      print file 
नहीं

गति के बारे में निश्चित, लेकिन स्पष्ट रूप से os.walk के बाद से पुनरावर्ती है, वे अलग अलग बातें करते हैं।

10

मापने/प्रोफाइलिंग से पहले अनुकूलन के लिए अपना समय बर्बाद न करें। अपने कोड को सरल और बनाए रखने में आसान बनाने पर ध्यान केंद्रित करें।

उदाहरण के लिए, आपके कोड में आप आरईसी प्रीकंपाइल करते हैं, जो आपको कोई गति वृद्धि नहीं देता है, क्योंकि पुनः मॉड्यूल में प्रीकंपील्ड आरईएस के आंतरिक re._cache हैं।

  1. यह आसान
  2. अगर यह धीमी है, तो प्रोफ़ाइल
  3. एक बार आप जानते हैं कि वास्तव में क्या कुछ तोड़ मरोड़ कर अनुकूलित करने और हमेशा दस्तावेज़ यह

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

+1

+1। –

+7

-1। ओपी ने "बड़ी डिस्क" का उल्लेख किया। इसके अलावा, कोड पहले से ही सरल है। इसके अलावा, ओपी अनुकूलन के चरण में प्रतीत होता है। यह कुछ समय के साथ प्रदर्शन से संबंधित प्रश्नों को त्यागने के लिए एसओ पर एक प्लेग है जैसे "समयपूर्व अनुकूलन ब्लब्ला की जड़ है" (जो वास्तव में Knuth की गलत व्याख्याएं हैं)। – kgadek

+4

-1 वास्तविक (पेशेवर) दुनिया में अनुकूलन महत्वपूर्ण है, जहां चीजें अक्सर बहुत बड़े पैमाने पर होती हैं। – Julius

0

*, ?, and character ranges expressed with [] will be correctly matched. This is done by using the os.listdir() and fnmatch.fnmatch() functions

मुझे लगता है कि यहां तक ​​कि ग्लोब के साथ आप अभी भी os.walk करने के लिए होता है, जब तक आप जानते हैं कि सीधे कितना गहरा अपने उप-निर्देशिका का पेड़ है।

बीटीडब्ल्यू। glob documentation में यह कहते हैं:

"? *,, और चरित्र पर्वतमाला [] के साथ व्यक्त सही ढंग से हो जाएगा) मिलान इस os.listdir() और fnmatch.fnmatch (का उपयोग करके किया जाता है काम करता है।"

मैं बस एक

for path, subdirs, files in os.walk(path): 
     for name in fnmatch.filter(files, search_str): 
      shutil.copy(os.path.join(path,name), dest) 
संबंधित मुद्दे