Python大ファイル解析の効率問題

3764 ワード

フォーラムの助けを求めることと自分で模索することを結びつけて、pythonの大きいファイルの解析の効率の問題を基本的に解決します.プロセスと結論をアーカイブし、必要な人の参考にします.
=======================
pythonが怒っているのを見て、pythonの懐に行ってぐずぐずして、list、dictの普通化の応用、多くのプログラミングを簡単にしました.
いい感じで、手書きで常用プログラムを書き始め、ぶつぶつ書き終わった.しかし、大規模なファイル処理に深刻な効率の問題があることに気づき、フォーラムに行って達人を探すしかなかった.
pythonはcsdnのフォーラムでも火をつけていないようで、主に管理者wn 0112に頼ってお互いに証明し合って改善しています.振り回されても、効率の向上は依然として数量レベルではありません.
あきらめかけて、c書き込みモジュールで基礎解析機能を実現しようとしたとき、ネット上の使い方を見て、霊機が現れて、やっと解決しました.
結果は容易ではなく、もっとくどくどして、感慨深い.皆さん、お構いなく.
===============================
環境以下に明記がない場合、pythonはpythonを採用する.orgの3.6.1バージョン、マシンAMD AthlonII x 3 450-*、win 10
議論の過程でいくつかの簡単な結論が見つかりました
  • pythonの稼働速度は、パソコンのソフト・ハードウェアの影響で、差は1倍程度ありません.【I 7 5500 U 2.40 G vs AMD Athlon II x 3 450-*】【win 7 vs win 10】【2.7 vs 3.5】他の人も忙しいので、私の手元にもあまり大きな機械がなく、深くありません.しかし、効率が1倍程度の差がある場合は、ハードウェアのアップグレードも考えられるという考え方を教えてください.o(^▽^)o
  • pythonのサイクル効率はまだ低いので、サイクルを使わないでください.J+=1だけして、1200 w回循環しても1.5秒かかります.K+=1を1つ多くするには3秒かかります.
  • 効率の問題が発見された場合、アルゴリズムを最適化し、アルゴリズムを最適化することができる.アルゴリズムも最適化できないので、モジュールを探して、関数を探します.

  • 一、大型ファイルの読み取り効率
    100 w行の大型データに直面
    with open(filename,"rb") as f:
        for fLine in f:
            pass
    
    rb方式が最も速く、100 w行は2.7秒をフルパスした.基本的には、中大型ファイルの処理効率のニーズを満たすことができます.rbをrに変更すると、6倍遅くなります.
    このようにファイルを処理し、fLineはbytesタイプであるが、pythonは自動的に断行し、読み出し内容を動作単位で処理することができる.
    行番号を取得する必要がある場合は、次の操作を行います.
    for lineNum, fline in enumerate(f) :
    インデックスが確立され、後続の検索位置決めのために使用される場合、従来のwinプログラミングの行番号位置決めは推奨されません.オフセット量を記録して位置決めすることが望ましい.
    import itertools
    for lineNum, fline in itertools.dropwhile(lambda x:x[0] < 1073109, enumerate(f)) :
    再配置の効率は大幅に向上します.
    二、テキスト処理効率
    テキスト処理は、一般にセパレータ処理、定長処理に分けられます.実はpython 3を重視しています.xシリーズはstringをunicode文字列に固化し、bytesタイプを使用します.ascIIを頻繁に処理するのではなく、unicodeはこの改善がどれほど良いか分からない.これも2.7を捨てて直接勉強する.xの原因.
    セパレータにはいろいろなsplit関数があるので、あまり言いません.
    ここでは定長ファイルについて話します.定長はunicode定長,ascII定長である.
    私が処理しているのはascii定長方式です.
    MS系プログラミングの経験で、全bytes処理で、効率が最高です.だからすべてbytesでstring処理を変換しません.結果は効率が憂慮される.20 w行のデータを解析し,12 sに直接上昇し,性能のボトルネックとなっている.
    最も簡単なループ分解解析データの使用を開始し,100 w行で20ドメインを解析し,最低5秒しか圧倒できなかった.正則で3.5秒を圧倒する【i 7マシンなら簡単サイクルでも3秒まで抑えられるらしい】.効率は依然として満足していない.
    あきらめかけて、c書き換え処理関数の自家製モジュール方式で効率を向上させ、cとpythonタイプの変換を見ると、関数が見えます.やっと完璧に解決した.コードは次のとおりです.
    import re
    import time
    import struct
    
    a=" abcdefghijklabcdefghijk"
    a="000000001111000002222222233333333000000004444444QAZ55555555000000006666666ABC                                                                                                                                                                                                                                                                                                 "
    ab=a.encode("GBK")
    aw=(2,3,2,2,2,2,2,2,2,2,2,2)
    aw=(12,9,4,8,15,3,8,15,3,80,200,15)
    
    awf=" ".join(map(lambda x:str(x)+"s",aw))
    
    print(awf)
    
    def tt5(argN,argByte):
    	#struck	
    	return struct.unpack(argN, argByte)
    def test5(arg1):
    	ticks=time.clock()
    	for x in range(arg1):
    		trs=tt5(awf, ab)
    	print("test4   %d ,  %16.6f "%(arg1,time.clock()-ticks))
    	print("  =",trs)
    test5(1000000)
    

    structモジュールは一般的に通信をバイトストリームに変換するために用いられ、ここでは100 w行で20ドメインを解析し、1秒【i 7がどれだけ速くできるかしばらく分からない】で基本的に需要を満たすことができる.
    unicodeの定長方式は、私がこんなに長い間処理していたのはめったに見られません.python 3をかじることも考えられます.xのstringモジュール.どうしても正則を使うことができなくて、100 w行3.5秒、受け入れることができます.
    注意:reモジュールはbytesを処理する場合、patternsはbytesでなければなりません.stringを処理する場合、patternsはstringでなければなりません.
    csdnのpythonフォーラムは、人が少なすぎます.pythonに本当に問題があるなら、pythonの人が多いフォーラムを探しましょう.
    ================================
    何日も苦労して、nつの方法の最適化を考えました.それはたくさんの血と涙ですね.くどくど言いたかった.
    見てみると、ニマ、過程はたくさんあります.皆さんも見たくないと思います.もういい、言わない:)