2017-01-02 13 views
0

私は、79行目から89行目を除く部分が〜0.16秒でコンパイルのようにうまく動作する130行のコードを持っていますが、10行(79-89間)の関数を追加した後は70-75秒。ライン毎にPython関数のパフォーマンス

4グルーピング番号:その関数のデータファイル(u.data)は、この形式の数値データの100000株です。問題は、(メインプログラムで実装する前に)テスト中に別のPythonファイルでその関数を実行したときに、0.15秒で動作することが示されていましたが、メインのコード(同じコード)ほとんど。ここに私のコードです:

""" Assignment 5: Movie Reviews 
    Date: 30.12.2016 
""" 
import os.path 
import time 
start_time = time.time() 

""" FUNCTIONS """ 


# Getting film names in film folder 
def get_film_name(): 
    name = '' 
    for word in read_data.split(' '): 
     if ('(' in word) == False: 
      name += word + ' ' 
     else: 
      break 
    return name.strip(' ') 


# Function for removing date for comparison 
def throw_date(string): 
    a_list = string.split()[:-1] 
    new_string = '' 
    for i in a_list: 
     new_string += i + ' ' 
    return new_string.strip(' ') 


def film_genre(film_name): 
    oboist = [] 
    genr_list = ['unknown', 'Action', 'Adventure', 'Animation', "Children's", 'Comedy', 'Crime', 'Documentary', 'Drama', 
       'Fantasy', 
       'Movie-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western'] 
    for item in u_item_list: 
     if throw_date(str(item[1])) == film_name: 
      for i in range(4, len(item)): 
       oboist.append(item[i]) 
    dictionary = dict(zip(genr_list, oboist)) 
    genres = '' 
    for key, value in dictionary.items(): 
     if value == '1': 
      genres += key + ' ' 
    return genres.strip(' ') 


def film_link(film_name): 
    link = '' 
    for item in u_item_list: 
     if throw_date(str(item[1])) == film_name: 
      link += item[3] 
    return link 


def film_review(film_name): 
    review = '' 
    for r, d, filess in os.walk('film'): 
     for fs in filess: 
      fullpat = os.path.join(r, fs) 
      with open(fullpat, 'r') as a_file: 
       data = a_file.read() 
       if str(film_name).lower() in str(data.split('\n', 1)[0]).lower(): 
        for i, line in enumerate(data): 
         if i > 1: 
          review += line 
      a_file.close() 
    return review 


def film_id(film_name): 
    for film in u_item_list: 
     if throw_date(film[1]) == film_name: 
      return film[0] 


def total_user_and_rate(film_name): 
    rate = 0 
    user = 0 
    with open('u.data', 'r') as data_file: 
     rate_data = data_file.read() 
     for l in rate_data.split('\n'): 
      if l.split('\t')[1] == film_id(film_name): 
       user += 1 
       rate += int(l.split('\t')[2]) 
    data_file.close() 
    print('Total User:' + str(int(user)) + '\nTotal Rate: ' + str(rate/user)) 



""" MAIN CODE""" 
review_file = open("review.txt", 'w') 
film_name_list = [] 
# Look for txt files and extract the film names 
for root, dirs, files in os.walk('film'): 
    for f in files: 
     fullpath = os.path.join(root, f) 
     with open(fullpath, 'r') as file: 
      read_data = file.read() 
      film_name_list.append(get_film_name()) 
     file.close() 

with open('u.item', 'r') as item_file: 
    item_data = item_file.read() 
item_file.close() 

u_item_list = [] 
for line in item_data.split('\n'): 
    temp = [word for word in line.split('|')] 
    u_item_list.append(temp) 


film_name_list = [i.lower() for i in film_name_list] 
updated_film_list = [] 
print(u_item_list) 

# Operation for review.txt 
for film_data_list in u_item_list: 
    if throw_date(str(film_data_list[1]).lower()) in film_name_list: 
     strin = film_data_list[0] + " " + film_data_list[1] + " is found in the folder" + '\n' 
     print(film_data_list[0] + " " + film_data_list[1] + " is found in the folder") 
     updated_film_list.append(throw_date(str(film_data_list[1]))) 
     review_file.write(strin) 
    else: 
     strin = film_data_list[0] + " " + film_data_list[1] + " is not found in the folder. Look at " + film_data_list[ 
      3] + '\n' 
     print(film_data_list[0] + " " + film_data_list[1] + " is not found in the folder. Look at " + film_data_list[3]) 
     review_file.write(strin) 

total_user_and_rate('Titanic') 

print("time elapsed: {:.2f}s".format(time.time() - start_time)) 

私の質問は、その理由がありますか?機能

( "total_user_and_rate(film_name)")

には問題がありますか?それとも他の部分に他の問題がありますか?それとも、ファイルのために正常ですか?助けてください、どんな助けもありがとう。

+1

私はあなたが何を求めているのか分かりません。なぜ、小さなテストファイルでコードが高速に実行されるのか、10万個の大量生産ファイルで「ゆっくり」実行されるのかを尋ねていますか? –

+0

いいえ、別のpyファイルの同じファイル(u.data)を使ってその関数をテストすると、ランタイムが2秒を超えないことを尋ねません。しかし、私はそれを私のメインプログラムに挿入し、その部分として使用し、同じファイル(u.data)に使用すると、この場合、プログラムは0.1秒から2秒のランタイムを持つ70秒で動作します。同様に、問題のある機能やプログラムですか? –

+1

各列は常に同じ桁数ですか?あなたはデータのいくつかの行を含めることができますか? – wwii

答えて

2

私はいくつかの不必要なものを見ます。

ファイル内のすべての行について、film_id(film_name)をループ内に呼び出すと、実際にはループの前に一度呼び出す必要があります。

ファイルを読み込む必要はありません。ファイルを分割して繰り返して、ファイルの行を繰り返してください。あなたが二回各ラインを分割

は、ちょうど

これらの変更のためのリファクタリング

たら、それを実行します。テストで

def total_user_and_rate(film_name): 
    rate = 0 
    user = 0 
    f_id = film_id(film_name) 
    with open('u.data', 'r') as data_file: 
     for line in data_file: 
      line = line.split('\t') 
      if line[1] == f_id: 
       user += 1 
       rate += int(line[2]) 
    data_file.close() 
    print('Total User:' + str(int(user)) + '\nTotal Rate: ' + str(rate/user)) 
+0

ありがとうございました。それは本当に動作します:) –

1

あなたはおそらくはるかに小さいu.itemファイルでテストしました。あるいは、film_idを確実にするために何か他のことをすることはずっと迅速でした。

あなたが持っている問題は、コンピュータが非常に高速であるため、実際には「ゆっくり」実行されている何かをやっている間に大きなミスを犯したときに気付かなかったことです。コンピュータ時間で。

if l.split('\t')[1] == film_id(film_name):行に1ミリ秒かかる場合は、012,ファイルを100,000行処理すると、total_user_and_rateの機能に100秒かかることが予想されます。

問題がfilm_id反復処理し、すべてのフィルムはすべての単一の行u.dataでのために正しいIDにを見つけるために、ということです。探しているfilm_idがu_item_listの冒頭近くにある場合は、機能がおそらく1ナノ秒未満になるため、幸運でしょう。しかし、u_item_listの終わり近くに新しい機能を実行するとすぐに、パフォーマンス上の問題が発生します。

wwiiは、total_user_and_rateの機能を最適化する方法を説明しました。しかし、u_item_listdictionaryに変更してパフォーマンスを向上させることもできます。これは、O(n)の複雑さからO(1)へのfilm_idのような関数のパフォーマンスを改善するでしょう。私。どれだけのフィルムが含まれていても、ナノ秒スケールで実行されます。

+0

あなたの助言をありがとう。私は本当に感謝しています –

+1

私はもっと長く続いていたすべてを見て、私はすべてのファイルを辞書に一度前処理するか、またはデータベースでさえ価値があると確信していました。しかし、再びそれは宿題です。 – wwii

関連する問題