2017-04-11 8 views
0

文字列中のパターンのすべての出現を見つける検索関数を書いています。私が必要とする出力の1つは、試合の現在のライン上のポジションです。これを行うには、改行のすべての場所を見つけて、行の位置を取得するために改行位置と共に一致位置を使用しています。私が問題を抱えているのは、改行位置を取得することです。私は定期的に大きなファイルを処理する予定であるため、できるだけ効率的にする必要があります。私はこの問題にいくつかの異なるアプローチを試みました。最初は:文字列内のすべての改行の位置を取得するためのFastet方法

これはずっと遅く、この部分の実行時間の80%近くを占めました。

次はこれを試しました。これは実際にパターンの検索を実装したのと似ています。

_newline_positions = [] 
    while _position < len(string): 
     _position = string.find("\n", _position) 
     if _position != -1: 
      _newline_positions.append(_position) 
     else: 
      break 
     _position += 1 

これは、最初の試みよりも効率的でしたが、約20%の時間の割合を約60%に削減しました。

_newline_positions = [match.start() for match in re.finditer("\n", string)] 

その検索時間の40%だけを取って最短かつ最も効率的な、しかし、検索機能で他のすべてと比較すると、それはまだである:

は、最後に私は正規表現を使用したソリューションを試してみましたはるかに時間のかかる部分です。

これを実行する他の方法は高速ですか、このタイプの正規表現ソリューションはこの問題に対して最も効率的ですか?

+1

なぜ、なぜあなたの変数名の先頭に先頭のアンダースコアを入れていますか?あなたは私を怒らせるためにやっていますか? –

+0

現在の行*に位置*が必要なだけで、ファイルを扱っています...なぜファイル全体を検索していますか?行間を繰り返して各行を検索するのではなく、一度にすべてのメモリを使用しますか? – user2357112

+2

これにC拡張を書くことができれば(あるいはおそらくcythonだけでも)、最初の解と同等のものが最も速くなり、Pythonの同等のものに比べて20倍から100倍のスピードアップが期待されます。 –

答えて

1

これは約2倍に高速私のテストでの正規表現のようにしています:

with open(file) as f: 
    newline_positions = [-1] 
    for v in f: 
    newline_positions.append(newline_positions[-1]+len(v)) 
    print(newline_positions[1:]) 

それはしてもしなくてもよいあなたに有用である可能性があなたのファイル内のすべての行にわたって繰り返しを必要としません。

+0

私はこれを試しましたが、私の場合は約2倍遅かったです。たぶん私が使用しているプロファイリング方法を変更する必要があるかもしれません... –

+0

もう少し作業した後、私はあなたが与えなかったメソッドが速く表示されますが、私のコードの大部分を削除するのに十分な情報を提供しました。非常にシンプルな2ループソリューションに変換します。全体的に、私は古いソリューションと比較して大きなファイルの約5倍の増加を得ました。 –

+0

おそらく私のテスト方法は変更する必要があります。小さなファイルで小さなサンプルサイズ。 – AShelly

関連する問題