標記這個作爲回答,並開始圍繞在速度問題真正出現一個較簡單的主題是Python的多文本提取性能問題VS Perl的等效
Python slow read performance issue
感謝迄今爲止的所有意見,非常有用
我有大約40M XML文件傳播(不均勻)跨約。 60K子目錄,該結構是基於一個10位數字分割這樣:
三十四分之一十二/ 56 /九十〇分之七十八/ files.xml
我有這是違背牽引的值的文件perl腳本單個字段輸出並打印值和文件名。 Perl腳本包裝在一個bash腳本中,該腳本在深度爲2的所有目錄的列表中運行最多12個並行實例,然後遍歷每個目錄並在發現它們時處理底層的文件。
以磁盤緩存了來自多個運行過程的UNIX時間返回約:
real 37m47.993s
user 49m50.143s
sys 54m57.570s
我想這個遷移到python腳本(作爲練習和測試),所以產生以下(後很多Python的方法不同的東西)閱讀了:
import glob, os, re
from multiprocessing import Pool
regex = re.compile(r'<field name="FIELDNAME">([^<]+)<', re.S)
def extractField(root, dataFile):
line = ''
filesGlob = root + '/*.xml'
global regex
for file in glob.glob(filesGlob):
with open(file) as x:
f = x.read()
match = regex.search(f)
line += file + '\t' + match.group(1) + '\n'
dataFile.write(line)
def processDir(top):
topName = top.replace("/", "")
dataFile = open('data/' + topName + '.data', 'w')
extractField(top, dataFile)
dataFile.close()
filesDepth5 = glob.glob('??/??/??/??/??')
dirsDepth5 = filter(lambda f: os.path.isdir(f), filesDepth5)
processPool = Pool(12)
processPool.map(processDir, dirsDepth5)
processPool.close()
processPool.join()
但無論我如何切的內容,當我運行UNIX時間給了我這樣的結果:
real 131m48.731s
user 35m37.102s
sys 48m11.797s
如果我在單個線程中針對一個小子集運行python和perl腳本(最終獲得完全緩存),因此沒有磁盤io(根據iotop),那麼腳本幾乎在相同時間運行。
到目前爲止我能想到的唯一結論是,文件io在python腳本中比在perl腳本中效率低得多,因爲它似乎是造成問題的io。
所以希望這是足夠的背景,我的問題是我做了一些愚蠢的事情或錯過了一個竅門,因爲我正在用盡想法,但不能相信io正在造成處理時間上的這種差異。
欣賞任何指針,並會根據需要提供更多信息。
感謝
硅
供參考的Perl腳本如下:
use File::Find;
my $cwd = `pwd`;
chomp $cwd;
find(\&hasxml, shift);
sub hasxml {
if (-d) {
my @files = <$_/*.xml>;
if (scalar(@files) > 0) {
process("$cwd/${File::Find::dir}/$_");
}
}
}
sub process {
my $dir = shift;
my @files = <$dir/*.xml>;
foreach my $file (@files) {
my $fh;
open($fh, "< $file") or die "Could not read file <$file>";
my $contents = do { local $/; <$fh> };
close($fh);
my ($id) = $contents =~ /<field name="FIELDNAME">([^<]+)<\/field>/s;
print "$file\t<$id>\n";
}
}
也許這將幫助你:http://stackoverflow.com/questions/14863224/efficient-reading-of-800-gb-xml-file-in-python-2-7 我認爲你應該剖析你的應用程序,看看它花費的最多時間,否則這是一個猜測... – 2014-10-01 22:44:35
我會看看謝謝,啊應該添加我正在閱讀的XML文件是每個至多4K大小,但我會嘗試緩衝提到看到。我試圖分析,但是當我運行 - python -m cProfile script.py它barf,我懷疑它不知道如何處理multiprocessing元素,但我承認我沒有詳細查看錯誤。 – Simon 2014-10-01 22:47:45
user/sys較低(提示python更快)但實際更高(暗示我們沒有並行化)...父/子協議很重要。嘗試'processPool.map(processDir,dirsDepth5,chunksize = 16)',它可以大批量發送作業,看看它是否有所作爲。 – tdelaney 2014-10-01 23:02:54