2016-09-14 1 views
2

私のPython GAEアプリケーションでは、次のコードスニペットは、ローカルで実行するよりも実際の生産がかなり遅いです。処理は次のようになります。GAE Pythonコードローカルよりも生産が少し遅い

  1. 約1 MBのテキストファイルがPOSTにロードされます。テキストファイルの各行は「項目」です。
  2. 私のコードは、テキストファイルから項目のリストを作成し、(コンパイルされたREとの比較によって)重複と妥当性をチェックします。ここで

コードは次のとおりです。

def process_items(self, text): 
    item_list = text.split() 
    item_set = set() 
    n_valid = 0 
    n_invalid = 0 
    n_dups = 0 
    out = "" 
    for item in item_list: 
     if item in item_set: 
      n_dups += 1 
      out += "DUPLICATE: %s\n" % item 
     elif valid_item(item): # This compares against a compiled RE 
      item_set.add(item) 
      n_valid += 1 
      out += "%s\n" % item 
     else: 
      n_invalid += 1 
      out += "INVALID: %s\n" % item 
    return out 

私は地元のdevのサーバー上でこれを実行すると、50,000行の1MBのファイルを処理するために、5秒かかります。

プロダクションでこれを実行すると、同じファイルが1分以上かかり、要求がタイムアウトします。ファイルのアップロードには約1秒しかかからないので、私はボトルネックが上記のコードであることを知っています。

以前は、ローカルコードとほぼ同じ速度でした。私はこのコードが変更されたとは思わないので、Googleの終了時に変更があった可能性があります。

なぜこのコードが現在生産中にはるかに遅いのでしょうか? このコードをもっと速くするためにできることは何ですか?どの行が重複していて、どの行が無効であるのかを示す注釈付きファイルをユーザーに返す必要があります。

EDIT:mgilsonさんのコメントに応えて

、私は次のコードを試みたが、それが実行時間に大きな違いを作りましたよ!以前は1分後にタイムアウトした処理にはわずか5秒しかかかりませんでした。 GAEはまだ予想よりも遅いです(比較的遅いサーバーのCPUを占めています)。しかし、改良されたアルゴリズムでは、今のところ問題ありません。

def process_items(self, text): 
    item_list = text.split() 
    item_set = set() 
    n_valid = 0 
    n_invalid = 0 
    n_dups = 0 
    for i, item in enumerate(item_list): 
     item = item.strip() 
     if item in item_set: 
      n_dups += 1 
      item_list[i] = "DUPLICATE: %s" % item 
     elif valid_item(item): # This compares against a compiled RE 
      item_set.add(item) 
      n_valid += 1 
      item_list[i] = item 
     else: 
      n_invalid += 1 
      item_list[i] = "INVALID: %s" % item 
    return "\n".join(item_list) 
+4

GAEで走っているのは本当に公正ではありません。設定した[インスタンスクラス](https://cloud.google.com/appengine/docs/about-the-standard-environment#instance_classes)に応じて、CPUの上限を600MHzにすることができます。ほとんどの個人的なコンピュータは今よりもはるかに高速です。 _might_の助けとなるすぐ明白な最適化は、結果をリストに累積し、 '+ ='を使用するのではなく、最後に '.join(results)'を返すことです。 Pythonではなぜ['.join()が+ =よりも速いのですか?](http://stackoverflow.com/q/39312099/748858)を参照してください。 – mgilson

+0

'process_items'を1行生成する' generate_items'遅い '+ = ' –

+0

@ mgilsonを取り除くことで、全体的な処理時間を短縮することができます。私のMacは2.2 GHzなので、GAEよりも3.7倍高速です。このPythonコードでは、私のMacはGAEより少なくとも12倍高速です。それはまだ多くの要因が不完全な比較になることを認識しているが、大きな矛盾のように見える。 –

答えて

4

これは、GAEの生産はローカルよりも実行速度が遅くなることは全く予想外ではありません - あなたのinstance classによっては、本番CPUは、ほとんどの開発者のコ​​ンピュータよりも大幅に遅い600MHzのような低い絞ることができます。あなたは物事をスピードアップするために行うことができます

ことの一つは、リストにあなたの結果を蓄積する(または発電機からそれらをもたらす)、その後、完全な結果を得るためにstr.joinを使用することです:地元のランニングを比較

def process_items(self, text): 
    item_list = text.split() 
    item_set = set() 
    n_valid = 0 
    n_invalid = 0 
    n_dups = 0 
    out = [] 
    for item in item_list: 
     if item in item_set: 
      n_dups += 1 
      out.append("DUPLICATE: %s\n" % item) 
     elif valid_item(item): # This compares against a compiled RE 
      item_set.add(item) 
      n_valid += 1 
      out.append("%s\n" % item) 
     else: 
      n_invalid += 1 
      out.append("INVALID: %s\n" % item) 
    return "".join(out) 
関連する問題